"""
/*
 * Copyright 2011 OpenWAF.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
 """
import sys
import copy

from JavaLangAST import Annotation, StmtBlock
from JavaLangAST import AnnotationMethod
from JavaLangAST import AnnotationType
from JavaLangAST import ArrayInitializer
from JavaLangAST import Block
from JavaLangAST import Class
from JavaLangAST import ClassBody
from JavaLangAST import ClassCreatorRest
from JavaLangAST import ClassOrInterfaceType
from JavaLangAST import CompilationUnit
from JavaLangAST import Creator
from JavaLangAST import CreatorArray
from JavaLangAST import CreatorInner
from JavaLangAST import ElementValuePair
from JavaLangAST import Enum
from JavaLangAST import EnumBody
from JavaLangAST import EnumConstant
from JavaLangAST import ExArguments
from JavaLangAST import ExArray
from JavaLangAST import ExArrayIndex
from JavaLangAST import ExCastExpression
from JavaLangAST import ExClass
from JavaLangAST import ExCreator
from JavaLangAST import ExDot
from JavaLangAST import ExIdentifier
from JavaLangAST import ExInnerCreator
from JavaLangAST import ExLiteral
from JavaLangAST import ExOperator
from JavaLangAST import ExParExpression
from JavaLangAST import ExPart
from JavaLangAST import ExPrimary
from JavaLangAST import ExPrimitiveType
from JavaLangAST import ExSuper
from JavaLangAST import ExThis
from JavaLangAST import ExType
from JavaLangAST import ExTypeArguments
from JavaLangAST import ExVoid
from JavaLangAST import Expression
from JavaLangAST import Field
from JavaLangAST import Import
from JavaLangAST import InnerCreator
from JavaLangAST import Interface
from JavaLangAST import InterfaceField
from JavaLangAST import InterfaceMethod
from JavaLangAST import Literal
from JavaLangAST import LocalVariableDeclaration
from JavaLangAST import Method
from JavaLangAST import Modifier
from JavaLangAST import OprAdditive
from JavaLangAST import OprAssign
from JavaLangAST import OprBinary
from JavaLangAST import OprEquality
from JavaLangAST import OprInstanceOf
from JavaLangAST import OprLogical
from JavaLangAST import OprMultiplicative
from JavaLangAST import OprPostfix
from JavaLangAST import OprRelational
from JavaLangAST import OprShift
from JavaLangAST import OprTernary
from JavaLangAST import OprUnary
from JavaLangAST import Parameter
from JavaLangAST import PrimitiveType
from JavaLangAST import QualifiedName
from JavaLangAST import StaticBlock
from JavaLangAST import StmtAssert
from JavaLangAST import StmtBlock
from JavaLangAST import StmtBreak
from JavaLangAST import StmtCatch
from JavaLangAST import StmtContinue
from JavaLangAST import StmtDoWhile
from JavaLangAST import StmtExp
from JavaLangAST import StmtExplicitConstructorInvocation
from JavaLangAST import StmtFor
from JavaLangAST import StmtForEach
from JavaLangAST import StmtIf
from JavaLangAST import StmtLabel
from JavaLangAST import StmtLocalVariableDeclaration
from JavaLangAST import StmtReturn
from JavaLangAST import StmtSemicolon
from JavaLangAST import StmtSwitch
from JavaLangAST import StmtSwitchBlock
from JavaLangAST import StmtSynch
from JavaLangAST import StmtThrow
from JavaLangAST import StmtTry
from JavaLangAST import StmtWhile
from JavaLangAST import Type
from JavaLangAST import TypeArgument
from JavaLangAST import TypeParameter
from JavaLangAST import VariableDeclarator
from LiteralReader import readLiteral
from Tokenizer import Token
from Tokenizer import TokenStream
from Tokenizer import tokenize
import datetime
import os
from ConfigReader import WAFConfig

import Semantic
import Analyzer
import UsageAnalyzer
import StaticCode
from Analyzer import SHelper, SClass, SGlobal
global total_tok_time
global total_compile_time

total_tok_time = datetime.datetime.now() - datetime.datetime.now()
total_compile_time = datetime.datetime.now() - datetime.datetime.now()

posErrors = []
global scus
scus = []

class WAFCompileError(StandardError):
	def __init__(self, uid, reftok):
		self.uid = uid
		self.ref = reftok
	def __str__(self):
		if self.ref == None:
			return "UID " + str(self.uid)
		else:
			return "UID " + str(self.uid) + " " + self.ref.data + " Line:" + str(self.ref.lineno) + " Offset:" + str(self.ref.pos)

def isKeyword(s):
	if not (s[0].isalpha() and s[0].islower()): return False
	return s in ["abstract", "assert", "boolean", "break", "byte", "case", "catch", "char", "class", "continue", "default", "do", "double", "else", "enum", "extends", "final", "finally", "float", "for", "goto", "if", "implements", "import", "instanceof", "int", "interface", "long", "native", "package", "private", "protected", "public", "return", "short", "static", "strictfp", "super", "new", "switch", "synchronized", "this", "throw", "throws", "transient", "try", "void", "volatile", "while", "null", "true", "false"]
def isPrimitiveType(s):
	if not (s[0].isalpha() and s[0].islower()): return False
	return s in["boolean", "char", "byte", "short", "int", "long", "float", "double"]
def toPrimitiveType(s):
	if not isPrimitiveType(s):return None#UNEXPECTED
	if s == "boolean":return PrimitiveType(PrimitiveType.BOOLEAN)
	if s == "char":return PrimitiveType(PrimitiveType.CHAR)
	if s == "byte":return PrimitiveType(PrimitiveType.BYTE)
	if s == "short":return PrimitiveType(PrimitiveType.SHORT)
	if s == "int":return PrimitiveType(PrimitiveType.INT)
	if s == "long":return PrimitiveType(PrimitiveType.LONG)
	if s == "float":return PrimitiveType(PrimitiveType.FLOAT)
	if s == "double":return PrimitiveType(PrimitiveType.DOUBLE)
	return None
################
## Annotation Declaration
################
def readAnnotationTypeDeclaration(ts):#complete #not_tested
	ci = ts.getCurrentIndex()
	modifiers = readModifiers(ts)
	tok = ts.getCurrentToken()
	if tok.data != "@":
		ts.setCurrentIndex(ci)
		return None
	tok = ts.getNextToken()
	if tok.data != "interface":
		ts.setCurrentIndex(ci)
		return None
	tok = ts.getNextToken()

	name = readIdentifier(ts)
	if name == None:
		raise WAFCompileError(1, ts.getCurrentToken())
	anno = AnnotationType()
	anno.modifiers = modifiers
	anno.name = name
	anno.body = readAnnotationTypeBody(ts)
	if anno.body == None:
		raise WAFCompileError(2, ts.getCurrentToken())
	return anno


def readAnnotationTypeBody(ts):
	ci = ts.getCurrentIndex()
	tok = ts.getCurrentToken()
	if tok.data != "{":return None
	values = []
	ts.getNextToken()
	while True:
		tok = ts.getCurrentToken()
		if tok.data == ";":
			ts.getNextToken()
			continue
		if tok.data == "}":break
		m = readAnnotationTypeElementDeclaration(ts)
		if m == None:break
		values.append(m)
	tok = ts.getCurrentToken()
	if tok.data != "}":
		raise WAFCompileError(3, ts.getCurrentToken())
	ts.getNextToken()
	return values




def readAnnotationTypeElementDeclaration(ts):
	ci = ts.getCurrentIndex()

	m = readAnnotationMethodDeclaration(ts)
	if m != None:return m
	ts.setCurrentIndex(ci)

	m = readInterfaceFieldDeclaration(ts)
	if m != None:return m
	ts.setCurrentIndex(ci)

	m = readNormalClassDeclaration(ts)
	if m != None:return m
	ts.setCurrentIndex(ci)

	m = readNormalInterfaceDeclaration(ts)
	if m != None:return m
	ts.setCurrentIndex(ci)

	m = readEnumDeclaration(ts)
	if m != None:return m
	ts.setCurrentIndex(ci)

	m = readAnnotationTypeDeclaration(ts)
	if m != None:return m
	ts.setCurrentIndex(ci)
	return None






def readAnnotationMethodDeclaration(ts):
	ci = ts.getCurrentIndex()
	modifiers = readModifiers(ts)
	typ = readType(ts)
	if typ == None:
		ts.setCurrentIndex(ci)
		return None#POSSIBLE_ERROR Expecting type for annotation type method declaration
	name = readIdentifier(ts)
	tok = ts.getCurrentToken()
	if tok.data != "(":
		ts.setCurrentIndex(ci)
		return None#POSSIBLE_ERROR Expecting ( in annotation method declaration
	tok = ts.getNextToken()
	if tok.data != ")":
		raise WAFCompileError(4, ts.getCurrentToken())
	am = AnnotationMethod()
	am.modifiers = modifiers
	am.name = name
	am.typ = typ
	tok = ts.getNextToken()
	if tok.data == ";":
		ts.getNextToken()
		return am
	if tok.data != "default":
		raise WAFCompileError(5, ts.getCurrentToken())
	tok = ts.getNextToken()
	am.elementvalue = readElementValue(ts)
	if am.elementvalue == None:
		raise WAFCompileError(6, ts.getCurrentToken())
	tok = ts.getCurrentToken()
	if tok.data != ";":
		raise WAFCompileError(7, ts.getCurrentToken())
	ts.getNextToken()
	return am




################
## Enum reading part
################
def readEnumDeclaration(ts):#complete #not_tested
	ci = ts.getCurrentIndex()
	modifiers = readModifiers(ts)
	tok = ts.getCurrentToken()
	if tok.data != "enum":
		ts.setCurrentIndex(ci)
		return None
	tok = ts.getNextToken()
	e = Enum()
	e.modifiers = modifiers
	e.name = readIdentifier(ts)
	if e.name == None:
		raise WAFCompileError(8, ts.getCurrentToken())
	tok = ts.getCurrentToken()
	if tok.data == "implements":
		tok = ts.getNextToken()
		e.implements = readTypeList(ts)
		if e.implements == None or len(e.implements) == 0:
			raise WAFCompileError(9, ts.getCurrentToken())
	e.body = readEnumBody(ts)
	if e.body == None:
		raise WAFCompileError(10, ts.getCurrentToken())
	return e

def readEnumBody(ts):
	ci = ts.getCurrentIndex()
	tok = ts.getCurrentToken()
	if tok.data != "{":return None
	tok = ts.getNextToken()
	eb = EnumBody()
	eb.constants = readEnumConstants(ts)
	tok = ts.getCurrentToken()
	#if tok.data==",":#as per grammar this ,(comma) is optional
	#	tok=ts.getNextToken()
	eb.decls = readEnumBodyDeclarations(ts)
	tok = ts.getCurrentToken()
	if tok.data != "}":
		raise WAFCompileError(11, ts.getCurrentToken())
	ts.getNextToken()
	return eb

def readEnumBodyDeclarations(ts):#complete #not_tested #note There could be error in grammar
	ci = ts.getCurrentIndex()
	tok = ts.getCurrentToken()
	if tok.data != ";":return None
	tok = ts.getNextToken()
	cb = readClassBodyDeclaration(ts)
	values = []
	while cb != None:
		values.append(cb)
		cb = readClassBodyDeclaration(ts)
	return values



def readEnumConstants(ts):#complete #not_tested
	ci = ts.getCurrentIndex()
	ec = readEnumConstant(ts)
	if ec == None:
		return None
	values = []
	values.append(ec)
	tok = ts.getCurrentToken()
	while tok.data == ",":
		tok = ts.getNextToken()
		before_start = ts.getCurrentIndex()
		ec = readEnumConstant(ts)
		if ec == None:
			ts.setCurrentIndex(before_start)
			break
		values.append(ec)
		tok = ts.getCurrentToken()
	return values
def readEnumConstant(ts):#complete #not_tested
	ci = ts.getCurrentIndex()
	anno = readAnnotation(ts)
	name = readIdentifier(ts)
	if name == None:
		ts.setCurrentIndex(ci)
		return None
	args = readArguments(ts)
	body = readClassBody(ts)

	ec = EnumConstant()
	ec.anno = anno
	ec.name = name
	ec.args = args
	ec.classbody = body
	return ec





#################################
## Expression Readig part
## Here list of symbols will be created for each expression
## But reading will be done  according to grammer
#################################
def readCreator(ts):#complete #not_tested
	ci = ts.getCurrentIndex()
	tok = ts.getCurrentToken()

	if tok.data == "new":
		cc = Creator()
		tok = ts.getNextToken()
		nwtypeargs = readNonWildcardTypeArguments(ts)
		typ = readClassOrInterfaceType(ts)
		if typ != None:
			ccr = readClassCreatorRest(ts)
			if ccr != None:
				cc.nwtypeargs = nwtypeargs
				cc.typ = typ
				cc.ccr = ccr
				return cc
		#we didnt found class creator , now look for array creator
		ts.setCurrentIndex(ci)
		cc.arraycreator = readArrayCreator(ts)
		if cc.arraycreator == None:
			ts.setCurrentIndex(ci)
			return None
		return cc


def readArrayCreator(ts):#complete #not_tested
	ci = ts.getCurrentIndex()
	ac = readArrayCreator_case1(ts)
	if ac != None:return ac
	ts.setCurrentIndex(ci)
	ac = readArrayCreator_case2(ts)
	if ac != None:return ac
	return None
def readArrayCreator_case1(ts):#complete #not_tested
	ci = ts.getCurrentIndex()
	tok = ts.getCurrentToken()
	if tok.data != "new":return None
	tok = ts.getNextToken()
	ac = CreatorArray()
	ac.exps = None
	ac.name = readCreatedName(ts)
	tok = ts.getCurrentToken()
	if tok.data != "[":
		ts.setCurrentIndex(ci)
		return None
	tok = ts.getNextToken()
	if tok.data != "]":
		ts.setCurrentIndex(ci)
		return None
	ac.arraydim = 1
	tok = ts.getNextToken()
	while tok.data == "[":
		tok = ts.getNextToken()
		if tok.data != "]":
			ts.setCurrentIndex(ci)
			return None
		tok = ts.getNextToken()
		ac.arraydim += 1
	ac.init = readArrayInitializer(ts)
	if ac.init == None:
		raise WAFCompileError(12, ts.getCurrentToken())
	return ac
def readArrayCreator_case2(ts):#complete #not_tested
	ci = ts.getCurrentIndex()
	tok = ts.getCurrentToken()
	if tok.data != "new":return None
	tok = ts.getNextToken()
	ac = CreatorArray()
	ac.name = readCreatedName(ts)
	tok = ts.getCurrentToken()
	if tok.data != "[":
		ts.setCurrentIndex(ci)
		return None
	ts.getNextToken()
	exps = []
	exp = readExpression(ts)
	if exp == None:
		ts.setCurrentIndex(ci)
		return None
	exps.append(exp)
	tok = ts.getCurrentToken()
	if tok.data != "]":
		ts.setCurrentIndex(ci)
		return None
	tok = ts.getNextToken()
	ac.arraydim = 1
	cci = ts.getCurrentIndex()
	while tok.data == "[":
		ts.getNextToken()
		exp = readExpression(ts)
		if exp == None:
			ts.setCurrentIndex(cci)
			break
		exps.append(exp)
		tok = ts.getCurrentToken()
		if tok.data != "]":
			raise WAFCompileError(13, ts.getCurrentToken())
		ac.arraydim += 1
		tok = ts.getNextToken()
		cci = ts.getCurrentIndex()
	tok = ts.getCurrentToken()
	while tok.data == "[":
		tok = ts.getNextToken()
		if tok.data != "]":
			ts.setCurrentIndex(ci)
			return None
		ac.arraydim += 1
		tok = ts.getNextToken()
	ac.exps = exps
	return ac




def readArrayInitializer(ts):#complete #not_tested ATLR's grammer for varibale initializer could be wrong last , condition ignored
	ci = ts.getCurrentIndex()
	tok = ts.getCurrentToken()
	if tok.data != "{":return None
	ai = ArrayInitializer()
	ts.getNextToken()
	vis = []
	vi = readVariableInitializer(ts)
	if vi != None:
		vis.append(vi)
		tok = ts.getCurrentToken()
		while tok.data == ",":
			tok = ts.getNextToken()
			if tok.data == "}":
				break#according to grammer it array initializer can have extra comma without following any initiallizer
			vi = readVariableInitializer(ts)
			if vi == None:
				raise WAFCompileError(14, ts.getCurrentToken())
			vis.append(vi)
			tok = ts.getCurrentToken()
	ai.part = vis
	tok = ts.getCurrentToken()
	if tok.data != "}":
		raise WAFCompileError(15, ts.getCurrentToken())
	tok = ts.getNextToken()
	return ai




def readVariableInitializer(ts):#complete #not_tested
	ci = ts.getCurrentIndex()
	ai = readArrayInitializer(ts)
	if ai != None:return ai
	ts.setCurrentIndex(ci)
	exp = readExpression(ts)
	if exp != None:return exp
	return None


def readCreatedName(ts):
	tok = ts.getCurrentToken()
	if isPrimitiveType(tok.data):
		ts.getNextToken()
		return toPrimitiveType(tok.data)
	else:
		ci = ts.getCurrentIndex()
		ct = readClassOrInterfaceType(ts)
		if ct == None:
			ts.setCurrentIndex(ci)
			return None
		return ct







def readCastExpression(ts):#complete #not_tested
	ci = ts.getCurrentIndex()
	tok = ts.getCurrentToken()
	if tok.data != "(":return None
	ce = readCastExpression_case1(ts)
	if ce != None:return ce
	ts.setCurrentIndex(ci)
	ce = readCastExpression_case2(ts)
	if ce != None:return ce
	ts.setCurrentIndex(ci)
	return None


def readCastExpression_case1(ts):#complete #not_tested  #note primtive
	tok = ts.getCurrentToken()
	if tok.data != "(":return None
	tok = ts.getNextToken()
	if isPrimitiveType(tok.data):
		datatype = toPrimitiveType(tok.data)
		tok = ts.getNextToken()
		if tok.data != ")":return None
		ts.getNextToken()
		exp = readUnaryExpression(ts)
		if exp == None:return None
		expc = ExCastExpression()
		expc.typ = datatype
		expc.exp = exp
		return expc
	return None
def readCastExpression_case2(ts):#complete #not_tested #primitive array or class
	tok = ts.getCurrentToken()
	if tok.data != "(":return None
	ts.getNextToken()
	datatype = readType(ts)
	if datatype == None:return None
	tok = ts.getCurrentToken()
	if tok.data != ")":return None
	ts.getNextToken()
	exp = readUnaryExpressionNotPlusMinus(ts)
	if exp == None:return None
	expc = ExCastExpression()
	expc.typ = datatype
	expc.exp = exp
	return expc



def readUnaryExpressionNotPlusMinus(ts):#complete #not_tested
	ci = ts.getCurrentIndex()
	tok = ts.getCurrentToken()
	if tok.data == "~":
		exps = []
		exps.append(ExOperator(OprUnary.TILDE))
		ts.getNextToken()
		part2 = readUnaryExpression(ts)
		if part2 == None:
			raise WAFCompileError(16, ts.getCurrentToken())
		exps.append(part2)
		return exps
	elif tok.data == "!":
		exps = []
		exps.append(ExOperator(OprUnary.NOT))
		ts.getNextToken()
		part2 = readUnaryExpression(ts)
		if part2 == None:
			raise WAFCompileError(17, ts.getCurrentToken())
		exps.append(part2)
		return exps
	else:
		ce = readCastExpression(ts)
		if ce != None:return [ce]
		ts.setCurrentIndex(ci)
		exps = []
		pe = readPrimary(ts)
		if pe == None:
			ts.setCurrentIndex(ci)
			return None
		ci = ts.getCurrentIndex()
		sel = readSelector(ts)
		while sel != None:
			exps = exps + sel
			ci = ts.getCurrentIndex()
			sel = readSelector(ts)
		ts.setCurrentIndex(ci)
		tok = ts.getCurrentToken()
		if tok.data == "++":
			exps.append(ExOperator(OprPostfix.INC))
			ts.getNextToken()
		elif tok.data == "--":
			exps.append(ExOperator(OprPostfix.DEC))
			ts.getNextToken()
		return [pe] + exps





def readUnaryExpression(ts):#complete #not_tested
	ci = ts.getCurrentIndex()
	tok = ts.getCurrentToken()
	exps = []
	if tok.data == "+":
		exps.append(ExOperator(OprUnary.POSITIVE))
	elif tok.data == "-":
		exps.append(ExOperator(OprUnary.NEGATIVE))
	elif tok.data == "++":
		exps.append(ExOperator(OprUnary.INC))
	elif tok.data == "--":
		exps.append(ExOperator(OprUnary.DEC))
	else:
		v = readUnaryExpressionNotPlusMinus(ts)
		if v == None:
			ts.setCurrentIndex(ci)
			return None
		return v

	ts.getNextToken()
	part2 = readUnaryExpression(ts)
	if part2 == None:
		raise WAFCompileError(18, ts.getCurrentToken())
	exps.append(part2)
	return exps





def readMultiplicativeExpression(ts):#complete #not_tested
	ci = ts.getCurrentIndex()
	part1 = readUnaryExpression(ts)
	if part1 == None:
		ts.setCurrentIndex(ci)
		return None
	tok = ts.getCurrentToken()
	if tok.data in ["*", "/", "%"]:
		exps = [part1]
		while tok.data in ["*", "/", "%"]:
			if tok.data == "*":
				exps.append(ExOperator(OprMultiplicative.MULTIPY))
			elif tok.data == "/":
				exps.append(ExOperator(OprMultiplicative.DIVIDE))
			else:
				exps.append(ExOperator(OprMultiplicative.MOD))
			ts.getNextToken()
			part2 = readUnaryExpression(ts)
			if part2 == None:
				raise WAFCompileError(19, ts.getCurrentToken())
			exps.append(part2)
			tok = ts.getCurrentToken()
		return exps
	else:
		return part1

def readAdditiveExpression(ts):#complete #not_tested
	ci = ts.getCurrentIndex()
	part1 = readMultiplicativeExpression(ts)
	if part1 == None:
		ts.setCurrentIndex(ci)
		return None
	tok = ts.getCurrentToken()
	if tok.data in ["+", "-"]:
		exps = [part1]
		while tok.data in ["+", "-"]:
			if tok.data == "+":
				exps.append(ExOperator(OprAdditive.PLUS))
			else:
				exps.append(ExOperator(OprAdditive.MINUS))
			ts.getNextToken()
			part2 = readMultiplicativeExpression(ts)
			if part2 == None:
				raise WAFCompileError(20, ts.getCurrentToken())
			exps.append(part2)
			tok = ts.getCurrentToken()
		return exps

	else:
		return part1
def readShiftExpression(ts):#complete #not_tested
	ci = ts.getCurrentIndex()
	part1 = readAdditiveExpression(ts)
	if part1 == None:
		ts.setCurrentIndex(ci)
		return None
	tok = ts.getCurrentToken()
	if tok.data in ["<<", ">"]:
		exps = [part1]
		while tok.data in ["<<", ">"]:
			if tok.data == "<<":
				exps.append(ExOperator(OprShift.LEFT_SHIFT))
				ts.getNextToken()
			elif tok.data == ">":
				ni = ts.getCurrentIndex()
				ntok = ts.getNextToken()
				if  ntok.data == ">":
					nntok = ts.getNextToken()
					if nntok.data == ">":
						eqch = ts.getNextToken()
						if eqch.data == "=":#this means this is >>>=
							ts.setCurrentIndex(ni)
							break

						exps.append(ExOperator(OprShift.RIGHT_RIGHT_SHIFT))
					elif nntok.data == "=":#this mean this is >>=
						ts.setCurrentIndex(ni)
						break
					else:
						exps.append(ExOperator(OprShift.RIGHT_SHIFT))


				else:
					ts.setCurrentIndex(ni)
					break


			part2 = readAdditiveExpression(ts)
			if part2 == None:
				raise WAFCompileError(21, ts.getCurrentToken())
			exps.append(part2)
			tok = ts.getCurrentToken()
		return exps

	else:
		return part1

def readRelationExpression(ts):#complete #not_tested
	ci = ts.getCurrentIndex()
	part1 = readShiftExpression(ts)
	if part1 == None:
		ts.setCurrentIndex(ci)
		return None
	tok = ts.getCurrentToken()
	if tok.data in ["<=", "<", ">"]:
		exps = [part1]
		while tok.data in ["<=", "<", ">"]:
			before_start = ts.getCurrentIndex()
			if tok.data == "<=":
				exps.append(ExOperator(OprRelational.LTE))
				ts.getNextToken()
			elif tok.data == ">":
				eqch = ts.getNextToken()
				if eqch.data == "=":
					exps.append(ExOperator(OprRelational.GTE))
					ts.getNextToken()
				elif eqch.data == ">":
					ts.setCurrentIndex(before_start)
					break
				else:
					exps.append(ExOperator(OprRelational.GT))
			else:
				exps.append(ExOperator(OprRelational.LT))
				ts.getNextToken()

			part2 = readShiftExpression(ts)
			if part2 == None:
				posErrors.append(WAFCompileError(22, ts.getCurrentToken()))
				ts.setCurrentIndex(ci)
				return None
			exps.append(part2)
			tok = ts.getCurrentToken()
		return exps
	else:
		return part1
def readInstanceOfExpression(ts):#complete #not_tested
	ci = ts.getCurrentIndex()
	part1 = readRelationExpression(ts)
	if part1 == None:
		ts.setCurrentIndex(ci)
		return None
	tok = ts.getCurrentToken()
	if tok.data != "instanceof":return part1
	exps = [part1]
	exps.append(ExOperator(OprInstanceOf.INSTANCEOF))
	ts.getNextToken()
	expt = readType(ts)
	if expt == None:
		raise WAFCompileError(23, ts.getCurrentToken())
	exp = ExType(expt)
	exps.append(exp)
	return exps



def readEqalityExpression(ts):#complete #not_tested
	ci = ts.getCurrentIndex()
	part1 = readInstanceOfExpression(ts)
	if part1 == None:
		ts.setCurrentIndex(ci)
		return None
	tok = ts.getCurrentToken()
	if tok.data in ["==", "!="]:
		exps = [part1]
		while tok.data == "==" or tok.data == "!=":
			if tok.data == "==":
				exps.append(ExOperator(OprEquality.ET))
			else:
				exps.append(ExOperator(OprEquality.NET))
			ts.getNextToken()
			part2 = readInstanceOfExpression(ts)
			if part2 == None:
				raise WAFCompileError(24, ts.getCurrentToken())
			exps.append(part2)
			tok = ts.getCurrentToken()
		return exps
	else:
		return part1

def readAndExpression(ts):#complete #not_tested
	ci = ts.getCurrentIndex()
	part1 = readEqalityExpression(ts)
	if part1 == None:
		ts.setCurrentIndex(ci)
		return None
	tok = ts.getCurrentToken()
	if tok.data == "&":
		exps = [part1]
		while tok.data == "&":
			exps.append(ExOperator(OprBinary.AND))
			ts.getNextToken()
			part2 = readEqalityExpression(ts)
			if part2 == None:
				raise WAFCompileError(25, ts.getCurrentToken())
			exps.append(part2)
			tok = ts.getCurrentToken()
		return exps
	else:
		return part1
def readExclusiveOrExpression(ts):#complete #not_tested
	ci = ts.getCurrentIndex()
	part1 = readAndExpression(ts)
	if part1 == None:
		ts.setCurrentIndex(ci)
		return None
	tok = ts.getCurrentToken()
	if tok.data == "^":
		exps = [part1]
		while tok.data == "^":
			exps.append(ExOperator(OprBinary.XOR))
			ts.getNextToken()
			part2 = readAndExpression(ts)
			if part2 == None:
				raise WAFCompileError(26, ts.getCurrentToken())
			exps.append(part2)
			tok = ts.getCurrentToken()
		return exps
	else:
		return part1
def readInclusiveOrExpression(ts):#complete #not_tested
	ci = ts.getCurrentIndex()
	part1 = readExclusiveOrExpression(ts)
	if part1 == None:
		ts.setCurrentIndex(ci)
		return None
	tok = ts.getCurrentToken()
	if tok.data == "|":
		exps = [part1]
		while tok.data == "|":
			exps.append(ExOperator(OprBinary.OR))
			ts.getNextToken()
			part2 = readExclusiveOrExpression(ts)
			if part2 == None:
				raise WAFCompileError(27, ts.getCurrentToken())
			exps.append(part2)
			tok = ts.getCurrentToken()
		return exps
	else:
		return part1
def readConditionalAndExpression(ts):#complete #not_tested
	ci = ts.getCurrentIndex()
	part1 = readInclusiveOrExpression(ts)
	if part1 == None:
		ts.setCurrentIndex(ci)
		return None
	tok = ts.getCurrentToken()
	if tok.data == "&&":
		exps = [part1]
		while tok.data == "&&":
			exps.append(ExOperator(OprLogical.AND))
			ts.getNextToken()
			part2 = readInclusiveOrExpression(ts)
			if part2 == None:
				raise WAFCompileError(28, ts.getCurrentToken())
			exps.append(part2)
			tok = ts.getCurrentToken()
		return exps
	else:
		return part1

def readConditionalOrExpression(ts):#complete #not_tested
	ci = ts.getCurrentIndex()
	part1 = readConditionalAndExpression(ts)
	if part1 == None:
		ts.setCurrentIndex(ci)
		return None
	tok = ts.getCurrentToken()
	if tok.data == "||":
		exps = [part1]
		while tok.data == "||":
			exps.append(ExOperator(OprLogical.OR))
			ts.getNextToken()
			part2 = readConditionalAndExpression(ts)
			if part2 == None:
				raise WAFCompileError(29, ts.getCurrentToken())
			exps.append(part2)
			tok = ts.getCurrentToken()
		return exps
	else:
		return part1




def readConditionalExpression(ts):#complete #not_tested

	ci = ts.getCurrentIndex()
	coe = readConditionalOrExpression(ts)
	if coe == None:
		ts.setCurrentIndex(ci)
		return None
	tok = ts.getCurrentToken()
	if tok.data != "?":return coe
	exps = [[coe]]
	tok = ts.getNextToken()
	exps.append(ExOperator(OprTernary.IF))
	rpart=[]
	exp = readExpressionImpl(ts)
	tok = ts.getCurrentToken()
	if tok.data != ":":
		raise WAFCompileError(30, ts.getCurrentToken())
	tok = ts.getNextToken()
	rpart.append(exp)
	rpart.append(ExOperator(OprTernary.ELSE))
	ce = readConditionalExpression(ts)
	if ce == None:
		raise WAFCompileError(31, ts.getCurrentToken())
	rpart.append(ce)
	exps.append(rpart)
	return exps


def readExpression(ts):#complete #not_tested
	parts = readExpressionImpl(ts)
	if parts == None or len(parts) == 0:return None
	ex = Expression()
	ex.parts = parts
	return ex

def readExpressionImpl(ts):#complete #not_tested
	ci = ts.getCurrentIndex()
	cexp = readConditionalExpression(ts)
	if cexp == None:
		ts.setCurrentIndex(ci)
		return None
	o = readAssignmentOperator(ts)
	if o == None:return cexp;
	sexp = readExpressionImpl(ts)
	if sexp == None:
		raise WAFCompileError(32, ts.getCurrentToken())
	return [cexp, o, sexp]



def readAssignmentOperator(ts):#complete #not_tested
	v = readAssignmentOperatorImpl(ts)
	if v == None:return None
	ts.getNextToken()
	return v

def readAssignmentOperatorImpl(ts):#complete #not_tested
	tok = ts.getCurrentToken()
	if tok.data == "=":return ExOperator(OprAssign.NORMAL)
	if tok.data == "+=":return ExOperator(OprAssign.PLUS)
	if tok.data == "-=":return ExOperator(OprAssign.MINUS)
	if tok.data == "*=":return ExOperator(OprAssign.MULTIPLY)
	if tok.data == "/=":return ExOperator(OprAssign.DIVIDE)
	if tok.data == "&=":return ExOperator(OprAssign.AND)
	if tok.data == "|=":return ExOperator(OprAssign.OR)
	if tok.data == "^=":return ExOperator(OprAssign.XOR)
	if tok.data == "%=":return ExOperator(OprAssign.MOD)
	if tok.data == "<<=":return ExOperator(OprAssign.LEFT_SHIFT)
	#if tok.data==">>=":return ExOperator(OprAssign.RIGHT_SHIFT)
	#if tok.data==">>>=":return ExOperator(OprAssign.RIGHT_RIGHT_SHIFT)
	if tok.data == ">":
		ci = ts.getCurrentToken()
		ntok = ts.getNextToken()
		if ntok.data == ">":
			nntok = ts.getNextToken()
			if nntok.data == "=":
				return ExOperator(OprAssign.RIGHT_SHIFT)
			elif nntok.data == ">":
				nnntok = ts.getNextToken()
				if nnntok.data == "=":
					return ExOperator(OprAssign.RIGHT_RIGHT_SHIFT)
		ts.setCurrentIndex(ci)
		return None
	return None

def readParExpression(ts):#complete #not_tested
	ci = ts.getCurrentIndex()
	tok = ts.getCurrentToken()
	if tok.data != "(":return None
	ts.getNextToken()
	exp = readExpression(ts)
	if exp == None:
		ts.setCurrentIndex(ci)
		return None
	tok = ts.getCurrentToken()
	if tok.data != ")":
		raise WAFCompileError(33, ts.getCurrentToken())
	ts.getNextToken()
	epe = ExParExpression()
	epe.exp = exp
	return epe


##primary
##   :   parExpression
##	|   'this'
##	('.' IDENTIFIER
##	)*
##	(identifierSuffix
##	)?
##	|   IDENTIFIER
##	('.' IDENTIFIER
##	)*
##	(identifierSuffix
##	)?
##	|   'super'
##	superSuffix
##	|   literal
##	|   creator
##	|   primitiveType
##	('[' ']'
##	)*
##	'.' 'class'
##	|   'void' '.' 'class'
##	;
def readPrimary(ts):
	values = readPrimaryImpl(ts)
	if values != None:
		e = ExPrimary()
		e.parts = values
		return e
	return None

def readPrimaryImpl(ts):
	ci = ts.getCurrentIndex()

	##   :   parExpression
	values = readPrimary_case1(ts)
	if values != None:return values
	ts.setCurrentIndex(ci)

	##	|   'this'
	##	('.' IDENTIFIER
	##	)*
	##	(identifierSuffix
	##	)?


	values = readPrimary_case2(ts)
	if values != None:return values
	ts.setCurrentIndex(ci)
	##IDENTIFIER
	## ('.' IDENTIFIER
	## )*
	## (identifierSuffix
	##)?
	values = readPrimary_case3(ts)
	if values != None:return values
	ts.setCurrentIndex(ci)
	##	|   'super'
	##	superSuffix

	values = readPrimary_case4(ts)
	if values != None:return values
	ts.setCurrentIndex(ci)
	## literal
	values = readPrimary_case5(ts)
	if values != None:return values
	ts.setCurrentIndex(ci)
	##	|   primitiveType
	##	('[' ']'
	##	  )*
	values = readPrimary_case6(ts)
	if values != None:return values
	ts.setCurrentIndex(ci)
	## |   'void' '.' 'class'
	values = readPrimary_case7(ts)
	if values != None:return values
	ts.setCurrentIndex(ci)

	## | creator
	c = readCreator(ts)
	if c != None:
		exc = ExCreator()
		exc.creator = c
		return [exc]

	ts.setCurrentIndex(ci)
	return None


def readPrimary_case1(ts):
	pe = readParExpression(ts)
	if pe != None:return [pe]
	return None
def readPrimary_case2(ts):
	tok = ts.getCurrentToken()
	if tok.data == "this":
		exps = []
		exps.append(ExThis())
		tok = ts.getNextToken()
		before_start = ts.getCurrentIndex()
		while tok.data == ".":
			ts.getNextToken()
			idf = readIdentifier(ts)
			if idf == None:
				ts.setCurrentIndex(before_start)
				break
			exps.append(ExDot())
			exidf = ExIdentifier()
			exidf.name = idf
			exps.append(exidf)
			tok = ts.getCurrentToken()
			before_start = ts.getCurrentIndex()
		suffix = readIdentifierSuffix(ts)
		if suffix == None:
			return exps
		exps = exps + suffix
		return exps
	return None
def readPrimary_case3(ts):
	tok = ts.getCurrentToken()
	idf = readIdentifier(ts)
	if idf == None:return None
	exps = []
	exidf = ExIdentifier()
	exidf.name = idf
	exps.append(exidf)
	tok = ts.getCurrentToken()
	cci = ts.getCurrentIndex()
	while tok.data == ".":
		ts.getNextToken()
		idf = readIdentifier(ts)
		if idf == None:
			ts.setCurrentIndex(cci)
			break
		exps.append(ExDot())
		exidf = ExIdentifier()
		exidf.name = idf
		exps.append(exidf)
		tok = ts.getCurrentToken()
		cci = ts.getCurrentIndex()
	suffix = readIdentifierSuffix(ts)
	if suffix == None:
		return exps
	exps = exps + suffix
	return exps
def readPrimary_case4(ts):
	tok = ts.getCurrentToken()
	if tok.data != "super": return None
	ts.getNextToken()
	exps = []
	exps.append(ExSuper())
	suffix = readSuperSuffix(ts)
	if suffix == None:
		raise WAFCompileError(34, ts.getCurrentToken())
	exps = exps + suffix
	return exps

def readPrimary_case5(ts):
	lit = readLiteral(ts)
	if lit == None:return None
	exp = ExLiteral()
	exp.literal = lit
	return [exp]

def readPrimary_case6(ts):
	tok = ts.getCurrentToken()
	if not isPrimitiveType(tok.data):return None

	pt = ExPrimitiveType()
	pt.typ = toPrimitiveType(tok.data)
	tok = ts.getNextToken()
	exps = []

	arraydim = 0
	while tok.data == "[":
		tok = ts.getNextToken()
		if not tok.data == "]":
			raise WAFCompileError(35, ts.getCurrentToken())
		arraydim += 1
		tok = ts.getNextToken()
	t = Type()
	t.pm_type = pt
	t.arraydim = arraydim
	exps.append(t)
	tok = ts.getCurrentToken()
	if tok.data != ".":return None
	tok = ts.getNextToken()
	if tok.data != "class":return None
	ts.getNextToken()
	exps.append(ExDot())
	exps.append(ExClass())
	#suffix=readIdentifierSuffix(ts)
	#if suffix!=None:
	#	return exps+suffix
	#else:
	return exps
def readPrimary_case7(ts):
	tok = ts.getCurrentToken()
	if tok.data != "void":return None
	tok = ts.getNextToken()
	if tok.data != ".":return None
	tok = ts.getNextToken()
	if tok.data != "class":return None
	ts.getNextToken()#accepeted
	exps = []
	exps.append(ExVoid())
	exps.append(ExDot())
	exps.append(ExClass())
	return exps

def readSelector(ts):
	ci = ts.getCurrentIndex()
	values = readSelector_case1(ts)
	if values != None:return values
	ts.setCurrentIndex(ci)
	values = readSelector_case2(ts)
	if values != None:return values
	ts.setCurrentIndex(ci)
	values = readSelector_case3(ts)
	if values != None:return values
	ts.setCurrentIndex(ci)
	values = readSelector_case4(ts)
	if values != None:return values
	ts.setCurrentIndex(ci)
	values = readSelector_case5(ts)
	if values != None:return values
	ts.setCurrentIndex(ci)
	values = readSelector_case6(ts)
	if values != None:return values
	ts.setCurrentIndex(ci)
	return None



def readSelector_case1(ts):
	tok = ts.getCurrentToken()
	if tok.data != ".":return None
	tok = ts.getNextToken()
	idf = readIdentifier(ts)
	if idf == None:return None
	args = readArguments(ts)
	exps = []
	exps.append(ExDot())
	ex = ExIdentifier()
	ex.name = idf
	exps.append(ex)
	if args != None:
		exa = ExArguments()
		exa.arguments = args
		exps.append(exa)
	return exps

def readSelector_case2(ts):
	tok = ts.getCurrentToken()
	if tok.data != ".":return None
	tok = ts.getNextToken()
	if tok.data != "this":return None
	tok = ts.getNextToken()
	exps = []
	exps.append(ExDot())
	exps.append(ExThis())
	return exps

def readSelector_case3(ts):
	tok = ts.getCurrentToken()
	if tok.data != ".":return None
	tok = ts.getNextToken()
	if tok.data != "super":return None
	tok = ts.getNextToken()
	suffix = readSuperSuffix(ts)
	if suffix == None:return None
	exps = []
	exps.append(ExDot())
	exps.append(ExSuper())
	exps = exps + suffix
	return exps


def readSelector_case4(ts):
	ic = readInnerCreator(ts)
	if ic == None:return None
	ex = ExInnerCreator()
	ex.creator = ic
	return [ex]

def readSelector_case5(ts):
	tok = ts.getCurrentToken()
	if tok.data != "[":return None
	tok = ts.getNextToken()
	exp = readExpression(ts)
	if exp == None:return None
	tok = ts.getCurrentToken()
	if tok.data != "]":
		raise WAFCompileError(36, ts.getCurrentToken())
	ts.getNextToken()
	ex = ExArrayIndex()
	ex.exp = exp
	return [ex]


def readSelector_case6(ts):
	tok = ts.getCurrentToken()
	if tok.data != ".":return None
	tok = ts.getNextToken()
	typeargs = readNonWildcardTypeArguments(ts)
	if typeargs == None:return None
	idf = readIdentifier(ts)
	if idf == None:return None
	args = readArguments(ts)
	if args == None:return None
	exps = []
	exps.append(ExDot())
	e = ExTypeArguments()
	e.typeargs = typeargs
	exps.append(e)
	ei = ExIdentifier()
	ei.name = idf
	exps.append(ei)
	ea = ExArguments()
	ea.arguments = args
	exps.append(ea)
	return exps



def readIdentifierSuffix(ts):
	ci = ts.getCurrentIndex()
	values = readIdentifierSuffix_case1(ts)
	if values != None:return values
	ts.setCurrentIndex(ci)

	values = readIdentifierSuffix_case2(ts)
	if values != None:return values
	ts.setCurrentIndex(ci)

	values = readIdentifierSuffix_case3(ts)
	if values != None:return values
	ts.setCurrentIndex(ci)

	values = readIdentifierSuffix_case4(ts)
	if values != None:return values
	ts.setCurrentIndex(ci)

	values = readIdentifierSuffix_case5(ts)
	if values != None:return values
	ts.setCurrentIndex(ci)

	values = readIdentifierSuffix_case6(ts)
	if values != None:return values
	ts.setCurrentIndex(ci)

	values = readIdentifierSuffix_case7(ts)
	if values != None:return values
	ts.setCurrentIndex(ci)

	values = readIdentifierSuffix_case8(ts)
	if values != None:return values
	ts.setCurrentIndex(ci)
	return None
def readIdentifierSuffix_case1(ts):
	tok = ts.getCurrentToken()
	if tok.data != "[":return None
	arraydim = 0
	while tok.data == "[":
		tok = ts.getNextToken()
		if tok.data != "]":
			posErrors.append(WAFCompileError(37, ts.getCurrentToken()))
			#ts.setCurrentIndex(ci)
			return None
		arraydim += 1
		tok = ts.getNextToken()
	if arraydim == 0:return None
	tok = ts.getCurrentToken()
	if tok.data != ".":return None
	tok = ts.getNextToken()
	if tok.data != "class":return None
	ts.getNextToken()
	exps = []
	a = ExArray()
	a.dimension = arraydim
	exps.append(a)
	exps.append(ExDot())
	exps.append(ExClass())
	return exps
def readIdentifierSuffix_case2(ts):
	tok = ts.getCurrentToken()
	if tok.data != "[":return None
	exps = []
	while tok.data == "[":
		ts.getNextToken()
		exp = readExpression(ts)
		if exp == None:return None
		tok = ts.getCurrentToken()
		if tok.data != "]":
			raise WAFCompileError(38, ts.getCurrentToken())
		ex = ExArrayIndex()
		ex.exp = exp
		exps.append(ex)
		tok = ts.getNextToken()
	return exps

def readIdentifierSuffix_case3(ts):
	args = readArguments(ts)
	if args == None:return None
	ex = ExArguments()
	ex.arguments = args
	return [ex]

def readIdentifierSuffix_case4(ts):
	tok = ts.getCurrentToken()
	if tok.data != ".":return None
	tok = ts.getNextToken()
	if tok.data != "class":return None
	ts.getNextToken()
	exps = []
	exps.append(ExDot())
	exps.append(ExClass())
	return exps

def readIdentifierSuffix_case5(ts):
	tok = ts.getCurrentToken()
	if tok.data != ".":return None
	tok = ts.getNextToken()
	if tok.data != "this":return None
	tok = ts.getNextToken()
	exps = []
	exps.append(ExDot())
	exps.append(ExThis())
	return exps

def readIdentifierSuffix_case6(ts):
	tok = ts.getCurrentToken()
	if tok.data != ".":return None
	tok = ts.getNextToken()
	if tok.data != "super":return None
	ts.getNextToken()
	args = readArguments(ts)
	if args == None:return None
	exps = []
	exps.append(ExDot())
	exps.append(ExSuper())
	exa = ExArguments()
	exa.arguments = args
	exps.append(exa)
	return exps

def readIdentifierSuffix_case7(ts):
	tok = ts.getCurrentToken()
	if tok.data != ".":return None
	tok = ts.getNextToken()
	typeargs = readNonWildcardTypeArguments(ts)
	if typeargs == None:return None
	idf = readIdentifier(ts)
	if idf == None:return None
	args = readArguments(ts)
	if args == None:return None
	exps = []
	exps.append(ExDot())
	e = ExTypeArguments()
	e.typeargs = typeargs
	exps.append(e)
	ei = ExIdentifier()
	ei.name = idf
	exps.append(ei)
	ea = ExArguments()
	ea.arguments = args
	exps.append(ea)
	return exps
def readIdentifierSuffix_case8(ts):
	ic = readInnerCreator(ts)
	if ic == None:return None
	ex = ExInnerCreator()
	ex.creator = ic
	return [ex]






def readInnerCreator(ts):
	ci = ts.getCurrentIndex()
	tok = ts.getCurrentToken()
	if tok.data != ".":return None
	tok = ts.getNextToken()
	if tok.data != "new":
		ts.setCurrentIndex(ci)
		return None
	tok = ts.getNextToken()
	nwta = readNonWildcardTypeArguments(ts)
	idf = readIdentifier(ts)
	if idf == None:
		ts.setCurrentIndex(ci)
		return None
	typeargs = readTypeArguments(ts)
	ccr = readClassCreatorRest(ts)
	if ccr == None:
		ts.setCurrentIndex(ci)
		return None
	ic = InnerCreator()
	ic.nwtypeargs = nwta
	ic.name = idf
	ic.typeargs = typeargs
	ic.classcreator = ccr
	return ic




def readClassCreatorRest(ts):
	args = readArguments(ts)
	if args == None:return None
	body = readClassBody(ts)
	ccr = ClassCreatorRest()
	ccr.args = args
	ccr.body = body
	return ccr






def readSuperSuffix(ts):
	ci = ts.getCurrentIndex()
	values = readSuperSuffix_case1(ts)
	if values != None:return values
	ts.setCurrentIndex(ci)
	values = readSuperSuffix_case2(ts)
	if values != None:return values
	ts.setCurrentIndex(ci)
	return None

def readSuperSuffix_case1(ts):
	args = readArguments(ts)
	if args == None:return None
	exa = ExArguments()
	exa.arguments = args
	return [exa]
def readSuperSuffix_case2(ts):
	tok = ts.getCurrentToken()
	if tok.data != ".":return None
	tok = ts.getNextToken()
	typeargs = readTypeArguments(ts)
	idf = readIdentifier(ts)
	if idf == None:return None
	args = readArguments(ts)

	exps = []
	exps.append(ExDot())
	if typeargs != None:
		eta = ExTypeArguments()
		eta.typeargs = typeargs
		exps.append(eta)
	ei = ExIdentifier()
	ei.name = idf
	exps.append(ei)
	if args != None:
		ea = ExArguments()
		ea.arguments = args
		exps.append(ea)
	return exps














#########################
## End Expression Reading
#########################

#####
## Statement Reader
#####
def readStatement(ts):#complete #not_tested #note:assert not supported yet
	tok = ts.getCurrentToken()
	if tok.data == ";":
		ts.getNextToken()
		return StmtSemicolon()
	elif tok.data == "{":
		st = readBlock(ts)
		if st == None:
			raise WAFCompileError(39, ts.getCurrentToken())
		stmt = StmtBlock()
		stmt.block = st
		return stmt
	elif tok.data == "if":
		st = readIfStatement(ts)
		if st == None:
			raise WAFCompileError(40, ts.getCurrentToken())
		return st
	elif tok.data == "for":
		st = readForStatement(ts)
		if st == None:
			raise WAFCompileError(41, ts.getCurrentToken())
		return st
	elif tok.data == "while":
		st = readWhileStatement(ts)
		if st == None:
			raise WAFCompileError(42, ts.getCurrentToken())
		return st
	elif tok.data == "do":
		st = readDoWhileStatement(ts)
		if st == None:
			raise WAFCompileError(43, ts.getCurrentToken())
		return st
	elif tok.data == "try":
		st = readTryStatement(ts)
		if st == None:
			raise WAFCompileError(44, ts.getCurrentToken())
		return st
	elif tok.data == "switch":
		st = readSwitchStatement(ts)
		if st == None:
			raise WAFCompileError(45, ts.getCurrentToken())
		return st
	elif tok.data == "synchronized":
		st = readSynchStatement(ts)
		if st == None:
			raise WAFCompileError(46, ts.getCurrentToken())
		return st
	elif tok.data == "return":
		st = readReturnStatement(ts)
		if st == None:
			raise WAFCompileError(47, ts.getCurrentToken())
		return st
	elif tok.data == "throw":
		st = readThrowStatement(ts)
		if st == None:
			raise WAFCompileError(48, ts.getCurrentToken())
		return st
	elif tok.data == "break":
		st = readBreakStatement(ts)
		if st == None:
			raise WAFCompileError(49, ts.getCurrentToken())
		return st
	elif tok.data == "continue":
		st = readContinueStatement(ts)
		if st == None:
			raise WAFCompileError(50, ts.getCurrentToken())
		return st
	elif tok.data == "assert":
		st = readAssertStatement(ts)
		if st == None:
			raise WAFCompileError(51, ts.getCurrentToken())
		return st
	ci = ts.getCurrentIndex()
	st = readExpressionStatement(ts)
	if st != None:return st
	ts.setCurrentIndex(ci)
	st = readLabelStatement(ts)
	if st != None: return st
	ts.setCurrentIndex(ci)
	return None#failed to read any statement


def readAssertStatement(ts):
	tok = ts.getCurrentToken()
	if tok.data != "assert":return None
	tok = ts.getNextToken()
	st = StmtAssert()
	st.exp1 = readExpression(ts)
	if st.exp1 == None:
		raise WAFCompileError(52, ts.getCurrentToken())
	tok = ts.getCurrentToken()
	if tok.data != ":":
		if tok.data == ";":
			ts.getNextToken()
			return st
		raise WAFCompileError(53, ts.getCurrentToken())
	tok = ts.getNextToken()
	st.exp2 = readExpression(ts)
	if st.exp2 == None:
		raise WAFCompileError(54, ts.getCurrentToken())
	tok = ts.getCurrentToken()
	if tok.data != ";":
		raise WAFCompileError(55, ts.getCurrentToken())
	ts.getNextToken()
	return st



"""
def readBlockStatement(ts):
	block=readBlock(ts)
	if block==None:return None
	st=StmtBlock()
	st.block=block
	return st
"""

def readIfStatement(ts):
	tok = ts.getCurrentToken()
	if tok.data != "if":return None
	st = StmtIf()
	ts.getNextToken()
	parexp = readParExpression(ts)
	if parexp == None:
		raise WAFCompileError(56, ts.getCurrentToken())
	stmt = readStatement(ts)
	if stmt == None:
		raise WAFCompileError(57, ts.getCurrentToken())
	tok = ts.getCurrentToken()
	elsestmt = None
	if tok.data == "else":
		ts.getNextToken()
		elsestmt = readStatement(ts)
		if elsestmt == None:
			raise WAFCompileError(58, ts.getCurrentToken())
	st.par = parexp
	st.stmt_if = stmt
	st.stmt_else = elsestmt
	return st

def readLocalVariableDeclarationStatement(ts):#complete #not_tested
	ci = ts.getCurrentIndex()
	lvd = readLocalVariableDeclaration(ts)
	if lvd == None:return None
	tok = ts.getCurrentToken()
	if tok.data != ";":
		ts.setCurrentIndex(ci)
		return None
	ts.getNextToken()
	st = StmtLocalVariableDeclaration()
	st.lvd = lvd
	return st
def getCopyOfType(typ):
    return copy.deepcopy(typ)

def readLocalVariableDeclaration(ts):#complete #not_tested
	ci = ts.getCurrentIndex()
	vm = readVariableModifiers(ts)
	typ = readType(ts)
	if typ == None:
		ts.setCurrentIndex(ci)
		return None
	arraydim = typ.arraydim
	vd = readVariableDeclarator(ts, typ)
	if vd == None:
		ts.setCurrentIndex(ci)
		return None
	tok = ts.getCurrentToken()
	vds = []
	vds.append(vd)
	while tok.data == ",":
		ts.getNextToken()
		t = getCopyOfType(typ)
		t.arraydim = arraydim
		vd = readVariableDeclarator(ts, t)
		if vd == None:
			ts.setCurrentIndex(ci)
			return None
		vds.append(vd)
		tok = ts.getCurrentToken()
	lvd = LocalVariableDeclaration()
	lvd.modifiers = vm
	lvd.vds = vds
	return lvd




def readVariableDeclarator(ts, typ):#complete #not_tested
	ci = ts.getCurrentIndex()
	idf = readIdentifier(ts)
	if idf == None:
		ts.setCurrentIndex(ci)
		return None
	arraydim = 0
	tok = ts.getCurrentToken()
	while tok.data == "[":
		tok = ts.getNextToken()
		if tok.data != "]":
			ts.setCurrentIndex(ci)
			return None
		arraydim += 1
		tok = ts.getNextToken()
	tok = ts.getCurrentToken()
	vinit = None
	if tok.data == "=":
		ts.getNextToken()
		vinit = readVariableInitializer(ts)
		if vinit == None:
			ts.setCurrentIndex(ci)
			return None
	vd = VariableDeclarator()
	typ.arraydim += arraydim
	vd.name = idf
	vd.init = vinit
	vd.typ = typ
	return vd

def readForStatement(ts):
	ci = ts.getCurrentIndex()
	st = readForStatement_case1(ts)
	if st != None:return st
	ts.setCurrentIndex(ci)
	st = readForStatement_case2(ts)
	if st != None:return st
	raise WAFCompileError(59, ts.getCurrentToken())

def readForStatement_case2(ts):#read for each
	tok = ts.getCurrentToken()
	if tok.data != "for":return None
	tok = ts.getNextToken()
	if tok.data != "(":
		raise WAFCompileError(60, ts.getCurrentToken())
	tok = ts.getNextToken()
	st = StmtForEach()
	vmodifiers = readVariableModifiers(ts)
	typ = readType(ts)
	if typ == None:
		raise WAFCompileError(61, ts.getCurrentToken())
	name = readIdentifier(ts)
	if name == None:
		raise WAFCompileError(62, ts.getCurrentToken())
	tok = ts.getCurrentToken()
	arraydim = 0
	while tok.data == "[":
		tok = ts.getNextToken()
		if  tok.data != "]":
			raise WAFCompileError(63, ts.getCurrentToken())
		tok = ts.getNextToken()
		arraydim += 1
	lvd = LocalVariableDeclaration()
	lvd.modifiers = vmodifiers
	vd = VariableDeclarator()
	vd.name = name
	vd.arraydim = arraydim
	vd.typ = typ
	lvd.vds = []
	lvd.vds.append(vd)
	st.vd = lvd
	if tok.data != ":":
		raise WAFCompileError(64, ts.getCurrentToken())
	tok = ts.getNextToken()
	st.exps = readExpression(ts)
	if st.exps == None:
		raise WAFCompileError(65, ts.getCurrentToken())
	tok = ts.getCurrentToken()
	if tok.data != ")":
		raise WAFCompileError(66, ts.getCurrentToken())
	tok = ts.getNextToken()
	st.stmt = readStatement(ts)
	if st.stmt == None:
		raise WAFCompileError(67, ts.getCurrentToken())
	return st


def readForStatement_case1(ts):#complete #not tested
	tok = ts.getCurrentToken()
	if tok.data != "for":return None
	tok = ts.getNextToken()
	if tok.data != "(":
		raise WAFCompileError(68, ts.getCurrentToken())
	tok = ts.getNextToken()
	st = StmtFor()
	st.init = readForInit(ts)
	tok = ts.getCurrentToken()
	if tok.data != ";":
		posErrors.append(WAFCompileError(69, ts.getCurrentToken()))
		return None
	tok = ts.getNextToken()
	st.cond = readExpression(ts)
	tok = ts.getCurrentToken()
	if tok.data != ";":
		raise WAFCompileError(70, ts.getCurrentToken())
	tok = ts.getNextToken()
	st.exps = readExpressionList(ts)
	tok = ts.getCurrentToken()
	if tok.data != ")":
		raise WAFCompileError(71, ts.getCurrentToken())
	ts.getNextToken()
	st.stmt = readStatement(ts)
	if st.stmt == None:
		raise WAFCompileError(72, ts.getCurrentToken())
	return st


def readForInit(ts):#complete #not_tested  need to implement for(int i:array)
	ci = ts.getCurrentIndex()
	lvd = readLocalVariableDeclaration(ts)
	if lvd != None:return lvd
	ts.setCurrentIndex(ci)
	values = readExpressionList(ts)
	if values != None:return values
	ts.setCurrentIndex(ci)

	return None#no problem in can be None



def readWhileStatement(ts):#complete #not_tested
	tok = ts.getCurrentToken()
	if tok.data != "while":return None
	ts.getNextToken()
	st = StmtWhile()
	st.par = readParExpression(ts)
	if st.par == None:
		raise WAFCompileError(73, ts.getCurrentToken())
	st.stmt = readStatement(ts)
	if st.stmt == None:
		raise WAFCompileError(74, ts.getCurrentToken())
	return st

def readDoWhileStatement(ts):#complete #not_tested
	tok = ts.getCurrentToken()
	if tok.data != "do":return None
	tok = ts.getNextToken()
	st = StmtDoWhile()
	st.stmt = readStatement(ts)
	if st.stmt == None:
		raise WAFCompileError(75, ts.getCurrentToken())
	tok = ts.getCurrentToken()
	if tok.data != "while":
		raise WAFCompileError(76, ts.getCurrentToken())
	tok = ts.getNextToken()
	st.par = readParExpression(ts)
	if st.par == None:
		raise WAFCompileError(77, ts.getCurrentToken())
	tok = ts.getCurrentToken()
	if tok.data != ";":
		raise WAFCompileError(78, ts.getCurrentToken())
	ts.getNextToken()
	return st

def readTryStatement(ts):#complete #not_tested
	ci = ts.getCurrentIndex()
	tok = ts.getCurrentToken()
	if tok.data != "try":return None
	tok = ts.getNextToken()
	st = StmtTry()
	st.tryblock = StmtBlock()
	st.tryblock.block=readBlock(ts)
	if st.tryblock == None:
		raise WAFCompileError(78, ts.getCurrentToken())
	catst = readCatchStatement(ts)
	st.catches = []
	while catst != None:
		st.catches.append(catst)
		catst = readCatchStatement(ts)
	tok = ts.getCurrentToken()
	if tok.data != "finally":
		if len(st.catches) == 0:
			raise WAFCompileError(80, ts.getCurrentToken())
		return st#no finnaly
	tok = ts.getNextToken()
	st.finallyblock =StmtBlock()
	st.finallyblock.block=readBlock(ts) 
	
	if st.finallyblock == None:
		raise WAFCompileError(81, ts.getCurrentToken())
	return st


def readCatchStatement(ts):#complete #not_tested
	ci = ts.getCurrentIndex()
	tok = ts.getCurrentToken()
	if tok.data != "catch":return None
	tok = ts.getNextToken()
	if tok.data != "(":
		raise WAFCompileError(82, ts.getCurrentToken())
	tok = ts.getNextToken()
	st = StmtCatch()
	st.param = readNormalParameter(ts)
	if st.param == None:
		raise WAFCompileError(83, ts.getCurrentToken())
	tok = ts.getCurrentToken()
	if tok.data != ")":
		raise WAFCompileError(84, ts.getCurrentToken())
	ts.getNextToken()
	st.block = StmtBlock()  
	st.block.block= readBlock(ts)
	if st.block == None:
		raise WAFCompileError(85, ts.getCurrentToken())
	return st

def readSwitchStatement(ts):#complete #not_tested
	tok = ts.getCurrentToken()
	if tok.data != "switch":return None
	tok = ts.getNextToken()
	st = StmtSwitch()
	st.par = readParExpression(ts)
	if st.par == None:
		raise WAFCompileError(86, ts.getCurrentToken())
	tok = ts.getCurrentToken()
	if tok.data != "{":
		raise WAFCompileError(87, ts.getCurrentToken())
	tok = ts.getNextToken()
	st.cases = readSwitchBlockStatementGroup(ts)
	tok = ts.getCurrentToken()
	if tok.data != "}":
		raise WAFCompileError(88, ts.getCurrentToken())
	ts.getNextToken()
	return st

def readSwitchBlockStatementGroup(ts):#complete #not_tested
	values = []
	ci = ts.getCurrentIndex()
	swb = readSwitchBlock(ts)
	while swb != None:#this could be just True
		values.append(swb)
		ci = ts.getCurrentIndex()
		swb = readSwitchBlock(ts)
	ts.setCurrentIndex(ci)#think once again
	return values#should never be executed just for safery

def readSwitchBlock(ts):#complete #not_tested
	tok = ts.getCurrentToken()
	if not (tok.data in ["case", "default"]):return None
	st = StmtSwitchBlock()
	if tok.data == "case":
		st.default = False
		tok = ts.getNextToken()
		st.exp = readExpression(ts)
		if st.exp == None:
			raise WAFCompileError(89, ts.getCurrentToken())
	else:
		st.default = True
		tok = ts.getNextToken()
	tok = ts.getCurrentToken()
	if tok.data != ":":
		raise WAFCompileError(90, ts.getCurrentToken())
	tok = ts.getNextToken()
	bstmt = readBlockStatement(ts)
	st.stmts = []#this could be 1 or zero so dont worry
	while bstmt != None:
		st.stmts.append(bstmt)
		bstmt = readBlockStatement(ts)
	return st

def readSynchStatement(ts):#complete #not_tested
	tok = ts.getCurrentToken()
	if tok.data != "synchronized":return None
	tok = ts.getNextToken()
	st = StmtSynch()
	st.par = readParExpression(ts)
	if st.par == None:
		raise WAFCompileError(91, ts.getCurrentToken())
	st.block = readBlock(ts)
	if st.block == None:
		raise WAFCompileError(92, ts.getCurrentToken())
	return st

def readReturnStatement(ts):#complete #not_tested
	tok = ts.getCurrentToken()
	if tok.data != "return":return None
	tok = ts.getNextToken()
	st = StmtReturn()
	if tok.data == ";":
		ts.getNextToken()
		return st
	st.exp = readExpression(ts)
	if st.exp == None:
		raise WAFCompileError(93, ts.getCurrentToken())
	tok = ts.getCurrentToken()
	if tok.data != ";":
		raise WAFCompileError(94, ts.getCurrentToken())
	ts.getNextToken()
	return st

def readThrowStatement(ts):#complete #not_tested
	tok = ts.getCurrentToken()
	if tok.data != "throw":return None
	tok = ts.getNextToken()
	st = StmtThrow()
	st.exp = readExpression(ts)
	if st.exp == None:
		raise WAFCompileError(95, ts.getCurrentToken())
	tok = ts.getCurrentToken()
	if tok.data != ";":
		raise WAFCompileError(96, ts.getCurrentToken())
	ts.getNextToken()
	return st

def readBreakStatement(ts):
	tok = ts.getCurrentToken()
	if tok.data != "break":return None
	tok = ts.getNextToken()
	st = StmtBreak()
	if tok.data == ";":
		ts.getNextToken()
		return st
	st.name = readIdentifier(ts)
	if st.name == None:
		raise WAFCompileError(97, ts.getCurrentToken())
	tok = ts.getCurrentToken()
	if tok.data != ";":
		raise WAFCompileError(98, ts.getCurrentToken())
	ts.getNextToken()
	return st

def readContinueStatement(ts):
	tok = ts.getCurrentToken()
	if tok.data != "continue":return None
	tok = ts.getNextToken()
	st = StmtContinue()
	if tok.data == ";":
		ts.getNextToken()
		return st
	st.name = readIdentifier(ts)
	if st.name == None:
		raise WAFCompileError(99, ts.getCurrentToken())
	tok = ts.getCurrentToken()
	if tok.data != ";":
		raise WAFCompileError(100, ts.getCurrentToken())
	ts.getNextToken()
	return st

def readExpressionStatement(ts):
	exp = readExpression(ts)
	if exp == None:return None
	st = StmtExp()
	st.exp = exp;
	tok = ts.getCurrentToken()
	if tok.data != ";":
		posErrors.append(WAFCompileError(101, ts.getCurrentToken()))
		return None
	ts.getNextToken()
	return st

def readLabelStatement(ts):#complete #not_tested
	ci = ts.getCurrentIndex()
	idf = readIdentifier(ts)
	if idf == None:
		ts.setCurrentIndex(ci)
		return None
	tok = ts.getCurrentToken()
	if tok.data != ":":
		ts.setCurrentIndex(ci)
		return None
	tok = ts.getNextToken()
	st = StmtLabel()
	st.name = idf
	st.stmt = readStatement(ts)
	if st.stmt == None:
		ts.setCurrentIndex(ci)
		return None#ERROR could be error
	#tok=ts.getCurrentToken()
	#if tok.data!=";":return None;#ERROR could be error
	#ts.getNextToken()
	return st



def readQualifiedName(ts):#complete #tested
	name = readIdentifier(ts)
	if name == None: return None
	qf = QualifiedName()
	qf.names = []
	qf.names.append(name)
	token = ts.getCurrentToken()
	while token.data == ".":
		ts.getNextToken()#move to next token
		name = readIdentifier(ts)
		if name == None: return None #syntax error
		qf.names.append(name)
		token = ts.getCurrentToken()
	return qf

def readQualifiedNameList(ts):#complete #not_tested
	qn = readQualifiedName(ts)
	if qn == None:return None
	values = []
	values.append(qn)
	tok = ts.getCurrentToken()
	while tok.data == ",":
		ts.getNextToken()
		qn = readQualifiedName(ts)
		if qn == None:
			raise WAFCompileError(104, ts.getCurrentToken())
		values.append(qn)
		tok = ts.getCurrentToken()
	return values


def isWrongIdStart(s):
	#if len(s)==1:
	return s in ['(', ')', '[', ']', '\\', '/', '^', '-', '?', '.', '*', '+', '{', '}', '&', ':', ';', ',', '<', '>', '=', '@', '!', '%', '|', '~', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '\"', '\'']

def readIdentifier(ts):#complete #tested
	tok = ts.getCurrentToken()
	if not isWrongIdStart(tok.data[0]):
		if not isKeyword(tok.data):
			ts.getNextToken()
			return tok
	return None

def readImport(ts):#complete #tested
	tok = ts.getNextToken();
	isstatic = False
	isstar = False
	if tok.data == "static":
		isstatic = True
		tok = ts.getNextToken()
	name = readIdentifier(ts)
	names = []
	if name == None:return None
	names.append(name)
	tok = ts.getCurrentToken()
	while tok.data == ".":
		tok = ts.getNextToken();
		name = readIdentifier(ts)
		tok = ts.getCurrentToken()
		if name == None:
			tok = ts.getCurrentToken()
			if tok.data == "*":
				ts.getNextToken()#move
				isstar = True
				break
			return None
		else:
			names.append(name)
	tok = ts.getCurrentToken()
	if tok.data != ";":return None
	ts.getNextToken()
	if len(names) == 1 and isstar == False:return None # as per java grammar
	return Import(names, isstar, isstatic)

def readAnnotation(ts):#complet #not_tested
	ci = ts.getCurrentIndex()
	if ts.getCurrentToken().data != "@":return None
	ts.getNextToken()
	name = readQualifiedName(ts)
	if name == None:
		ts.setCurrentIndex(ci)
		return None
	anno = Annotation()
	anno.name = name
	tok = ts.getCurrentToken()
	if tok.data != "(":
		return anno
	tok = ts.getNextToken()
	if tok.data == ")":
		ts.getNextToken()
		return anno
	before_value = ts.getCurrentIndex()
	anno.value = readElementValue(ts)
	if anno.value != None:
		tok = ts.getCurrentToken()
		if tok.data == ")":
			ts.getNextToken()
			return anno
	ts.setCurrentIndex(before_value)
	tok = ts.getCurrentToken()
	anno.valuepairs = readElementValuePairs(ts)
	if anno.valuepairs == None:
		raise WAFCompileError(105, ts.getCurrentToken())
	tok = ts.getCurrentToken()
	if tok.data != ")":
		raise WAFCompileError(106, ts.getCurrentToken())
	ts.getNextToken()
	return anno

def readElementValuePairs(ts):
	ci = ts.getCurrentIndex()
	value = readElementValuePair(ts)
	if value == None:
		ts.setCurrentIndex(ci)
		return None
	tok = ts.getCurrentToken()
	values = []
	values.append(value)
	while tok.data == ",":
		ts.getNextToken()
		value = readElementValuePair(ts)
		if value == None:
			raise WAFCompileError(107, ts.getCurrentToken())
		values.append(value)
		tok = ts.getCurrentToken()
	return values

def readElementValuePair(ts):#complete #not_tested
	ci = ts.getCurrentIndex()
	name = readIdentifier(ts)
	tok = ts.getCurrentToken()
	if tok.data != "=":
		ts.setCurrentIndex(ci)
		return None#POSSIBLE_ERROR Expecing =
	tok = ts.getNextToken()
	value = readElementValue(ts)
	if value == None:
		raise WAFCompileError(108, ts.getCurrentToken())
	e = ElementValuePair()
	e.name = name
	e.value = value
	return e
def readElementValue(ts):
	ci = ts.getCurrentIndex()
	ce = readConditionalExpression(ts)
	if ce != None and len(ce) > 0:
		ex = Expression()
		ex.parts = ce
		return ex
	ts.setCurrentIndex(ci)
	anno = readAnnotation(ts)
	if anno != None:return anno
	ts.setCurrentIndex(ci)
	evi = readElementValueInitializer(ts)
	if evi == None:
		raise WAFCompileError(109, ts.getCurrentToken())
	return evi


def readElementValueInitializer(ts):
	tok = ts.getCurrentToken()
	if tok.data != "{":return None
	ci = ts.getCurrentIndex()
	tok = ts.getNextToken()
	if tok.data == "}":
		tok = ts.getNextToken()
		return []
	values = []
	ev = readElementValue(ts)
	if ev == None:
		raise WAFCompileError(110, ts.getCurrentToken())
	values.append(ev)
	tok = ts.getCurrentToken()
	while tok.data == ",":
		ts.getNextToken()
		ev = readElementValue(ts)
		if ev == None:
			raise WAFCompileError(111, ts.getCurrentToken())
		values.append(ev)
		tok = ts.getCurrentToken()
	if tok.data != "}":
		raise WAFCompileError(112, ts.getCurrentToken())
	ts.getNextToken()
	return values

def readTypeArgument(ts):#complete #not_tested
	tok = ts.getCurrentToken()
	if tok.data == "?":
		t = TypeArgument()
		t.isany = True
		tok = ts.getNextToken()
		if tok.data in ["extends", "super"]:
			ts.getNextToken()
			if tok.data == "extends":
				t.extends = readType(ts)
				if t.extends == None:
					raise WAFCompileError(113, ts.getCurrentToken())
			else:
				t.superclass = readType(ts)
				if t.superclass == None:
					raise WAFCompileError(114, ts.getCurrentToken())
		return t
	else:
		t = TypeArgument()
		t.typ = readType(ts)

		if t.typ == None:return None
		tok = ts.getCurrentToken()
		t.isany = False
		if tok.data in ["extends", "super"]:
			ts.getNextToken()
			if tok.data == "extends":
				t.extends = readType(ts)
				if t.extends == None:
					raise WAFCompileError(165, ts.getCurrentToken())
			else:
				t.superclass = readType(ts)
				if t.superclass == None:
					raise WAFCompileError(166, ts.getCurrentToken())
		return t


def readTypeArguments(ts):#complete #not_tested
	tok = ts.getCurrentToken()
	if tok.data != "<":return None
	tok = ts.getNextToken()
	typearg = readTypeArgument(ts)
	if typearg == None:return None
	values = []
	values.append(typearg)
	tok = ts.getCurrentToken()
	while tok.data == ",":
		ts.getNextToken()
		typearg = readTypeArgument(ts)
		if typearg == None:
			raise WAFCompileError(115, ts.getCurrentToken())
		values.append(typearg)
		tok = ts.getCurrentToken()
	if tok.data != ">":
		posErrors.append(WAFCompileError(116, ts.getCurrentToken()))
		return None
	ts.getNextToken()#move
	return values


def readClassOrInterfaceType(ts):#complete #not_tested
	name = readIdentifier(ts)
	if name == None:return None
	names = []
	names.append(name)
	tok = ts.getCurrentToken()
	while tok.data == ".":
		cci = ts.getCurrentIndex()
		tok = ts.getNextToken()
		if tok.data == ".":
			ts.setCurrentIndex(cci)
			break
		name = readIdentifier(ts)
		if name == None:
			posErrors.append(WAFCompileError(117, ts.getCurrentToken()))
			return None
		names.append(name)
		tok = ts.getCurrentToken()
	typeargs = readTypeArguments(ts)
	coi = ClassOrInterfaceType()
	coi.names = names
	coi.typeargs = typeargs
	return coi#be care full

def readTypeList(ts):#complete #not_tested
	typ = readType(ts)
	if typ == None:return None
	values = []
	values.append(typ)
	tok = ts.getCurrentToken()
	while tok.data == ",":
		ts.getNextToken()
		typ = readType(ts)
		if typ == None:
			raise WAFCompileError(118, ts.getCurrentToken())
		values.append(typ)
		tok = ts.getCurrentToken()
	return values

def readType(ts):#complete #not_tested
	tok = ts.getCurrentToken()
	if isPrimitiveType(tok.data):
		t = Type()
		t.pm_type = toPrimitiveType(tok.data)
		t.arraydim = 0
		tok = ts.getNextToken()
		while tok.data == "[":
			tok = ts.getNextToken()
			if tok.data != "]":
				raise WAFCompileError(119, ts.getCurrentToken())
			t.arraydim += 1
			tok = ts.getNextToken()
		return t
	else:
		data = readClassOrInterfaceType(ts)
		if data == None:return None#this is ok NO_ERROR
		t = Type()
		t.coit = data
		t.arraydim = 0
		tok = ts.getCurrentToken()
		while tok.data == "[":
			tok = ts.getNextToken()
			if tok.data != "]":
				posErrors.append(WAFCompileError(120, ts.getCurrentToken()))
				return None
			t.arraydim += 1
			tok = ts.getNextToken()
		return t


def readTypeBound(ts):#complete #not_tested
	typ = readType(ts)
	if typ == None:return None
	values = []
	values.append(typ)
	tok = ts.getCurrentToken()
	while tok.data == "&":
		ts.getNextToken()
		typ = readType(ts)
		if typ == None:return None
		values.append(typ)
		tok = ts.getCurrentToken()
	return values

def readTypeParameter(ts):#complete #not_tested
	name = readIdentifier(ts)
	if name == None:return None
	tp = TypeParameter()
	tp.name = name
	tok = ts.getCurrentToken()
	if tok.data == "extends":
		ts.getNextToken()
		tp.bound = readTypeBound(ts)
		if tp.bound == None:
			raise WAFCompileError(121, ts.getCurrentToken())
	return tp

def readTypeParameters(ts):#complete #not_tested
	tok = ts.getCurrentToken()
	if tok.data != "<":return None
	tok = ts.getNextToken()
	tp = readTypeParameter(ts)
	if tp == None:return None#expecting type parameter
	tok = ts.getCurrentToken()
	values = []
	values.append(tp)
	while tok.data == ",":
		ts.getNextToken()
		tp = readTypeParameter(ts)
		if tp == None:
			raise WAFCompileError(122, ts.getCurrentToken())
		values.append(tp)
		tok = ts.getCurrentToken()
	if tok.data != ">":
		raise WAFCompileError(123, ts.getCurrentToken())
	ts.getNextToken()#move >
	return values


def readModifiers(ts):#incomplet #not_tested
	tok = ts.getCurrentToken()
	values = []
	while True:
		if tok.data == "@":
			ci = ts.getCurrentIndex()
			ntok = ts.getNextToken()
			if ntok.data == "interface":
				ts.setCurrentIndex(ci)
				return values
			ts.setCurrentIndex(ci)
			anno = readAnnotation(ts)
			if anno == None:return None
			values.append(anno)
		elif tok.data in ["public", "protected", "private", "static", "abstract", "final", "native", "synchronized", "transient", "volatile", "strictfp"]:
			values.append(tok)
			ts.getNextToken()
		else:
			break
		tok = ts.getCurrentToken()
	return values
def readVariableModifiers(ts):#complete #not_tested
	values = []
	while True:
		anno = readAnnotation(ts)
		if anno == None:
			tok = ts.getCurrentToken()
			if tok.data == "final":
				tok = ts.getNextToken()
				values.append(tok)
			else:
				break
		else:
			values.append(anno)
	return values


def readNormalParameter(ts):#complete #not_tested
	ci = ts.getCurrentIndex()
	modifiers = readVariableModifiers(ts)
	typ = readType(ts)
	if typ == None:
		ts.setCurrentIndex(ci)
		return None
	name = readIdentifier(ts)
	if name == None:
		ts.setCurrentIndex(ci)
		return None
	p = Parameter()
	p.modifier = modifiers
	p.name = name
	p.typ = typ
	tok = ts.getCurrentToken()
	while tok.data == "[":
		tok = ts.getNextToken()
		if tok.data != "]":
			raise WAFCompileError(124, ts.getCurrentToken())
		p.typ.arraydim += 1
		tok = ts.getNextToken()
	return p
def readFormalParameters(ts):
	tok = ts.getCurrentToken()
	if tok.data != "(":return None
	ci = ts.getCurrentIndex()
	ts.getNextToken()
	pars = readFormalParameterDecl(ts)
	if pars == None:pars = []
	#pars could be none #TODO:review this condition or we can assign empty array here
	tok = ts.getCurrentToken()
	if tok.data != ")":
		raise WAFCompileError(125, ts.getCurrentToken())
	ts.getNextToken()
	return pars

def readFormalParameterDecl(ts):
	ci = ts.getCurrentIndex()
	values = readFormalParameterDecl_case2(ts)
	if values != None:return values
	ts.setCurrentIndex(ci)
	values = readFormalParameterDecl_case1(ts)
	if values != None:return values
	ts.setCurrentIndex(ci)
	values = readFormalParameterDecl_case3(ts)
	if values != None:return values
	ts.setCurrentIndex(ci)
	return None



def readFormalParameterDecl_case1(ts):
	ep = readEllipsisParameterDecl(ts)
	if ep != None:return [ep]
	return None

def readFormalParameterDecl_case2(ts):#complete #not_tested
	np = readNormalParameter(ts)
	if np == None:return None
	values = []
	tok = ts.getCurrentToken()
	values.append(np)
	while tok.data == ",":
		ts.getNextToken()
		np = readNormalParameter(ts)
		if np == None:
			posErrors.append(WAFCompileError(126, ts.getCurrentToken()))
			return None
		values.append(np)
		tok = ts.getCurrentToken()
	return values


def readFormalParameterDecl_case3(ts):
	np = readNormalParameter(ts)
	if np == None:return None
	values = []
	tok = ts.getCurrentToken()
	values.append(np)
	while tok.data == ",":
		tok = ts.getNextToken()

		np = readNormalParameter(ts)
		if np == None:
			ep = readEllipsisParameterDecl(ts)
			if ep == None:
				raise WAFCompileError(127, ts.getCurrentToken())
			values.append(ep)
			return values
		values.append(np)
		tok = ts.getCurrentToken()
	return None#this should never get executed



def readEllipsisParameterDecl(ts):
	modifiers = readVariableModifiers(ts)
	typ = readType(ts)
	if typ == None:return None
	tok = ts.getCurrentToken()
	if tok.data != ".":return None
	tok = ts.getNextToken()
	if tok.data != ".":return None
	tok = ts.getNextToken()
	if tok.data != ".":return None
	ts.getNextToken()
	idf = readIdentifier(ts)
	if idf == None:
		raise WAFCompileError(128, ts.getCurrentToken())
	p = Parameter()
	p.isellipsis = True
	p.modifier = modifiers
	p.name = idf
	p.typ = typ
	return p

def readNonWildcardTypeArguments(ts):#complete #not_tested
	tok = ts.getCurrentToken()
	if tok.data != "<":return None
	tok = ts.getNextToken()
	values = readTypeList(ts)
	if values == None or len(values) == 0:
		raise WAFCompileError(129, ts.getCurrentToken())
	tok = ts.getCurrentToken()
	if tok.data != ">":
		raise WAFCompileError(130, ts.getCurrentToken())
	ts.getNextToken()
	return values

def readExpressionList(ts):
	ex = readExpression(ts)
	if ex == None:return None
	values = []
	values.append(ex)
	tok = ts.getCurrentToken()
	while tok.data == ",":
		ts.getNextToken()
		ex = readExpression(ts)
		if ex == None:
			raise WAFCompileError(131, ts.getCurrentToken())
		values.append(ex)
		tok = ts.getCurrentToken()
	return values

def readArguments(ts):#complete #not_tested
	tok = ts.getCurrentToken()
	if tok.data != "(":return None
	tok = ts.getNextToken()
	if tok.data == ")":
		ts.getNextToken()
		return []#no arguments
	values = readExpressionList(ts)
	tok = ts.getCurrentToken()
	if tok.data != ")":
		raise WAFCompileError(132, ts.getCurrentToken())
	ts.getNextToken()
	return values

def readExplicitConstructorInvocationStatement(ts):#complete #not_tested #note case 2 us not handled for
	return readExplicitConstructorInvocationStatement_case1(ts)

def readExplicitConstructorInvocationStatement_case1(ts):#complete #not_tested
	ci = ts.getCurrentIndex()
	nw_typeargs = readNonWildcardTypeArguments(ts)
	tok = ts.getCurrentToken()
	if not (tok.data in ["this", "super"]):
		ts.setCurrentIndex(ci)
		return None
	is_this = False
	is_super = False
	if tok.data == "this":is_this = True
	if tok.data == "super":is_super = True
	ts.getNextToken()
	arguments = readArguments(ts)
	if arguments == None:
		posErrors.append(WAFCompileError(133, ts.getCurrentToken()))
		ts.setCurrentIndex(ci)
		return None
	st = StmtExplicitConstructorInvocation()
	st.is_super = is_super
	st.is_this = is_this
	st.arguments = arguments
	st.nw_typeargs = nw_typeargs
	tok = ts.getCurrentToken()
	if tok.data != ";":
		raise WAFCompileError(134, ts.getCurrentToken())
	ts.getNextToken()
	return st

def readInterfaceFieldDeclaration(ts):#complete #not_tested
	ci = ts.getCurrentIndex()
	modifiers = readModifiers(ts)
	typ = readType(ts)
	if typ == None:
		ts.setCurrentIndex(ci)
		return None#POSSIBLE_ERROR
		arraydim = typ.arraydim
	decls = []
	decl = readVariableDeclarator(ts, typ)
	if decl == None:
		ts.setCurrentIndex(ci)
		return None
	decls.append(decl)

	tok = ts.getCurrentToken()
	while tok.data == ",":
		ts.getNextToken()
		t = getCopyOfType(typ)
		t.arraydim = arraydim
		decl = readVariableDeclarator(ts, t)
		if decl == None:
			raise WAFCompileError(135, ts.getCurrentToken())
		decls.append(decl)
		tok = ts.getCurrentToken()
	if tok.data != ";":
		raise WAFCompileError(136, ts.getCurrentToken())
	ts.getNextToken()
	f = InterfaceField()
	f.modifiers = modifiers
	f.declarators = decls
	return f

def readInterfaceMethodDeclaration(ts):#complete #not_tested
	ci = ts.getCurrentIndex()
	modifiers = readModifiers(ts)
	typepars = readTypeParameters(ts)
	tok = ts.getCurrentToken()
	is_void = False
	rtype = None
	if tok.data == "void":
		is_void = True
		tok = ts.getNextToken()
	else:
		rtype = readType(ts)
		if rtype == None:
			posErrors.append(WAFCompileError(137, ts.getCurrentToken()))
			ts.setCurrentIndex(ci)
			return None
	name = readIdentifier(ts)
	if name == None:
		raise WAFCompileError(138, ts.getCurrentToken())
	formalpars = readFormalParameters(ts)
	if formalpars == None:
		posErrors.append(WAFCompileError(139, ts.getCurrentToken()))
		ts.setCurrentIndex(ci)
		return None
	#TODO:as per ANTLR grammar []* dont know why this could be bug in grammar
	#TODO:update ..this is not a bug.. we have updated this for normal class
	m = InterfaceMethod()
	m.name = name
	m.is_void = is_void
	m.rettyp = rtype
	m.modifiers = modifiers
	m.typepars = typepars
	m.pars = formalpars
	tok = ts.getCurrentToken()
	if tok.data == "throws":
		tok = ts.getNextToken()
		m.throws = readQualifiedNameList(ts)
		if m.throws == None:
			raise WAFCompileError(140, ts.getCurrentToken())
	tok = ts.getCurrentToken()
	if tok.data != ";":
		raise WAFCompileError(141, ts.getCurrentToken())
	ts.getNextToken()
	return m




def readFieldDeclaration(ts):#complete #not_tested
	ci = ts.getCurrentIndex()
	modifiers = readModifiers(ts)
	typ = readType(ts)
	if typ == None:
		ts.setCurrentIndex(ci)
		return None#POSSIBLE_ERROR
	arraydim = typ.arraydim
	decls = []
	decl = readVariableDeclarator(ts, typ)
	if decl == None:
		ts.setCurrentIndex(ci)
		return None
	decls.append(decl)

	tok = ts.getCurrentToken()
	while tok.data == ",":
		ts.getNextToken()
		t = getCopyOfType(typ)
		t.arraydim = arraydim
		decl = readVariableDeclarator(ts, t)
		if decl == None:
			raise WAFCompileError(142, ts.getCurrentToken())
		decls.append(decl)
		tok = ts.getCurrentToken()
	if tok.data != ";":
		posErrors.append(WAFCompileError(143, ts.getCurrentToken()))
		ts.setCurrentIndex(ci)
		return None
	ts.getNextToken()
	f = Field()
	f.modifiers = modifiers
	f.declarators = decls
	return f

def readMethodDeclaration(ts):
	ci = ts.getCurrentIndex()
	m = readMethodDeclaration_case2(ts)
	if m != None:return m
	ts.setCurrentIndex(ci)
	m = readMethodDeclaration_case1(ts)
	return m


def readMethodDeclaration_case1(ts):#complete
	ci = ts.getCurrentIndex()
	tok = ts.getCurrentToken()
	line_start=tok.lineno
	offset_start=tok.pos
	modifiers = readModifiers(ts)
	typepars = readTypeParameters(ts)
	name = readIdentifier(ts)
	if name == None:
		ts.setCurrentIndex(ci)
		return None
	formalpars = readFormalParameters(ts)
	if formalpars == None:
		ts.setCurrentIndex(ci)
		return None
	m = Method()
	m.line_start=line_start
	m.offset_start=offset_start
	m.modifiers = modifiers
	m.typepars = typepars
	m.name = name
	m.pars = formalpars
	tok = ts.getCurrentToken()
	if tok.data == "throws":
		ts.getNextToken()
		m.throws = readQualifiedNameList(ts)
		if m.throws == None:
			raise WAFCompileError(144, ts.getCurrentToken())
	tok = ts.getCurrentToken()
	if tok.data != "{":
		ts.setCurrentIndex(ci)
		return None
	tok = ts.getNextToken()
	m.explconinv = readExplicitConstructorInvocationStatement(ts)
	m.stmts = readBlockStatements(ts)
	tok = ts.getCurrentToken()
	if tok.data != "}":
		raise WAFCompileError(145, ts.getCurrentToken())
	ts.getNextToken()
	tok = ts.getCurrentToken()
	m.line_end=tok.lineno
	m.offset_end=tok.pos
	return m

def readMethodDeclaration_case2(ts):#complete #not_tested	
	ci = ts.getCurrentIndex()
	tok = ts.getCurrentToken()
	line_start=tok.lineno
	offset_start=tok.pos
	modifiers = readModifiers(ts)
	typeargs = readTypeParameters(ts)
	tok = ts.getCurrentToken()
	is_void = False
	rtype = None
	if tok.data == "void":
		is_void = True
		tok = ts.getNextToken()
	else:
		rtype = readType(ts)
		if rtype == None:
			posErrors.append(WAFCompileError(146, ts.getCurrentToken()))
			ts.setCurrentIndex(ci)
			return None
	name = readIdentifier(ts)
	if name == None:
		posErrors.append(WAFCompileError(147, ts.getCurrentToken()))
		ts.setCurrentIndex(ci)
		return None

	formalpars = readFormalParameters(ts)
	if formalpars == None:
		raise WAFCompileError(148, ts.getCurrentToken())
	#TODO:as per ANTLR grammar []* dont know why this could be bug in grammar
	#UPDATE:this is not bug , array dim will be counted in array ref:source of java.io.ByteArrayOutputStream
	tok = ts.getCurrentToken()
	while tok.data == "[":
		if is_void == True:
			raise WAFCompileError(149, ts.getCurrentToken())
		tok = ts.getNextToken()
		if tok.data != "]":
			raise WAFCompileError(150, ts.getCurrentToken())
		rtype.arraydim += 1
		tok = ts.getNextToken()
	m = Method()
	m.line_start=line_start
	m.offset_start=offset_start
	m.name = name
	m.is_void = is_void
	m.rettyp = rtype
	m.modifiers = modifiers
	m.typepars = typeargs
	m.pars = formalpars
	tok = ts.getCurrentToken()
	if tok.data == "throws":
		tok = ts.getNextToken()
		m.throws = readQualifiedNameList(ts)
		if m.throws == None:
			raise WAFCompileError(151, ts.getCurrentToken())
	tok = ts.getCurrentToken()
	cti = ts.getCurrentIndex()
	if tok.data == ";":
		last_token = ts.tokens[cti - 1]
		data = last_token.data.strip()
		if data.startswith("/*"):
			m.native_code = data
		ts.getNextToken()
		tok = ts.getCurrentToken()
		m.line_end=tok.lineno
		m.offset_end=tok.pos
		return m
	m.block = readBlock(ts)
	if m.block == None:
		raise WAFCompileError(152, ts.getCurrentToken())
	tok = ts.getCurrentToken()
	m.line_end=tok.lineno
	m.offset_end=tok.pos
	return m


def readMemberDeclaration(ts):#complete #not_tested
	ci = ts.getCurrentIndex()
	m = readFieldDeclaration(ts)
	if m != None:return m
	ts.setCurrentIndex(ci)

	m = readMethodDeclaration(ts)
	if m != None:return m
	ts.setCurrentIndex(ci)

	m = readClassDeclaration(ts)
	if m != None:return m
	ts.setCurrentIndex(ci)

	m = readInterfaceDeclaration(ts)
	if m != None:return m
	ts.setCurrentIndex(ci)
	return m

def readBlock(ts):#complete #not_tested
	tok = ts.getCurrentToken()
	if tok.data != "{":return None
	ci = ts.getCurrentIndex()
	ts.getNextToken()
	values = readBlockStatements(ts)
	if values == None:
		raise WAFCompileError(153, ts.getCurrentToken())
	tok = ts.getCurrentToken()
	if tok.data != "}":
		raise WAFCompileError(154, ts.getCurrentToken())

	ts.getNextToken()
	return values

def readBlockStatements(ts):
	values = []
	ci = ts.getCurrentIndex()
	tok = ts.getCurrentToken()
	st = readBlockStatement(ts)
	while st != None:
		values.append(st)
		ci = ts.getCurrentIndex()
		tok = ts.getCurrentToken()
		if tok.data == "}":break
		st = readBlockStatement(ts)

	ts.setCurrentIndex(ci)
	return values
def readBlockStatement(ts):
	tok = ts.getCurrentToken()
	if tok.data == "}":return None#TO Prevent deadlock
	ci = ts.getCurrentIndex()
	st = readLocalVariableDeclarationStatement(ts)
	if st != None:return st
	ts.setCurrentIndex(ci)
	st = readStatement(ts)
	if st != None:return st
	ts.setCurrentIndex(ci)
	st = readClassDeclaration(ts)
	if st != None:return st
	return None
def readClassBodyDeclaration(ts):#complete #not_tested
	ci = ts.getCurrentIndex()
	m = readMemberDeclaration(ts)
	if m != None:
		tok = ts.getCurrentToken()
		if tok != None and tok.data == ";":
			ts.getNextToken()
		return m
	ts.setCurrentIndex(ci)
	m = readClassBodyStaticBlock(ts)
	if m != None:
		tok = ts.getCurrentToken()
		if tok != None and tok.data == ";":
			ts.getNextToken()
		return m
	ts.setCurrentIndex(ci)
	return None

def readClassBodyStaticBlock(ts):
	tok = ts.getCurrentToken()
	is_static=False
	if tok.data == "static":
		ts.getNextToken()
		is_static=True
	block = readBlock(ts)
	if block != None:
		sb = StaticBlock()
		sb.block = block
		sb.static = is_static
		return sb
	return None







def readClassBody(ts):#complete #not_tested #note only ; condition not handled
	ci = ts.getCurrentIndex()
	tok = ts.getCurrentToken()
	if tok.data != "{":return None#POSSIBLE_ERROR
	ts.getNextToken()
	values = []
	m = readClassBodyDeclaration(ts)
	while m != None:
		values.append(m)
		m = readClassBodyDeclaration(ts)
	tok = ts.getCurrentToken()
	if tok.data != "}":
		raise WAFCompileError(155, ts.getCurrentToken())
	ts.getNextToken()
	return values


def readClassDeclaration(ts):#complete #not_tested
	ci = ts.getCurrentIndex()
	cd = readNormalClassDeclaration(ts)
	if cd != None:
		tok = ts.getCurrentToken()
		if tok != None and tok.data == ";":
			ts.getNextToken()
		return cd
	ts.setCurrentIndex(ci)
	ed = readEnumDeclaration(ts)
	if ed != None:
		tok = ts.getCurrentToken()
		if tok != None and tok.data == ";":
			ts.getNextToken()
		return ed
	ts.setCurrentIndex(ci)
	return None

def readNormalClassDeclaration(ts):#complete #not_tested
	start_index = ts.getCurrentIndex()
	modifiers = readModifiers(ts)
	tok = ts.getCurrentToken()
	if tok.data != "class":
		ts.setCurrentIndex(start_index)
		return None
	tok = ts.getNextToken()
	cls = Class()
	cls.modifiers = modifiers
	cls.name = readIdentifier(ts)
	if cls.name == None:
		raise WAFCompileError(156, ts.getCurrentToken())
	cls.typepars = readTypeParameters(ts)
	tok = ts.getCurrentToken()
	if tok.data == "extends":
		ts.getNextToken()
		cls.extends = readType(ts)
		if cls.extends == None:
			raise WAFCompileError(157, ts.getCurrentToken())
	tok = ts.getCurrentToken()
	if tok.data == "implements":
		ts.getNextToken()
		cls.implements = readTypeList(ts)
		if cls.implements == None:
			raise WAFCompileError(158, ts.getCurrentToken())
	cls.body = readClassBody(ts)
	if cls.body == None:
		raise WAFCompileError(159, ts.getCurrentToken())
	return cls


def readInterfaceDeclaration(ts):
	ci = ts.getCurrentIndex()
	at = readAnnotationTypeDeclaration(ts)
	if at != None:
		tok = ts.getCurrentToken()
		if tok != None and tok.data == ";":
			ts.getNextToken()
		return at
	ts.setCurrentIndex(ci)
	ni = readNormalInterfaceDeclaration(ts)
	if ni != None:
		tok = ts.getCurrentToken()
		if tok != None and tok.data == ";":
			ts.getNextToken()
		return ni
	ts.setCurrentIndex(ci)
	return None

def readNormalInterfaceDeclaration(ts):#complete #note tested
	ci = ts.getCurrentIndex()
	modifiers = readModifiers(ts)
	tok = ts.getCurrentToken()
	if tok.data != "interface":
		ts.setCurrentIndex(ci)
		return None
	tok = ts.getNextToken()
	i = Interface()
	i.modifiers = modifiers
	i.name = readIdentifier(ts)
	if i.name == None:
		raise WAFCompileError(160, ts.getCurrentToken())
	i.typepars = readTypeParameters(ts)
	tok = ts.getCurrentToken()
	if tok.data == "extends":
		tok = ts.getNextToken()
		i.extends = readTypeList(ts)
		if i.extends == None:
			raise WAFCompileError(161, ts.getCurrentToken())
	i.body = readInterfaceBody(ts)
	if i.body == None:
		raise WAFCompileError(162, ts.getCurrentToken())
	return i

def readInterfaceBody(ts):
	ci = ts.getCurrentIndex()
	tok = ts.getCurrentToken()
	if tok.data != "{":
		return None
	tok = ts.getNextToken()
	values = []
	while True:
		tok = ts.getCurrentToken()
		if tok.data == ";":
			tok = ts.getNextToken()
			continue
		if tok.data == ";":break
		cci = ts.getCurrentIndex()
		m = readInterfaceBodyDeclaration(ts)
		if m == None:
			ts.setCurrentIndex(cci)
			break
		values.append(m)
	tok = ts.getCurrentToken()
	if tok.data != "}":
		raise WAFCompileError(163, ts.getCurrentToken())
	ts.getNextToken()
	return values

def readInterfaceBodyDeclaration(ts):#complete #not_tested #note only semicolon condition is handle in readInterfaceBody
	ci = ts.getCurrentIndex()
	m = readInterfaceMethodDeclaration(ts)
	if m != None:return m
	ts.setCurrentIndex(ci)

	m = readInterfaceFieldDeclaration(ts)
	if m != None:return m
	ts.setCurrentIndex(ci)

	m = readInterfaceDeclaration(ts)
	if m != None:return m
	ts.setCurrentIndex(ci)

	m = readClassDeclaration(ts)
	if m != None:return m
	ts.setCurrentIndex(ci)

	return None

def readTypeDeclaration(ts):
	if ts.isEnd():return None
	tok = ts.getCurrentToken()
	if ts.isEnd():return None
	ci = ts.getCurrentIndex();
	cls = readClassDeclaration(ts)
	if cls != None:return cls
	ts.setCurrentIndex(ci)
	cls = readInterfaceDeclaration(ts)
	return cls










def read_CompilationUnit(ts):
	cu = CompilationUnit()
	anno = readAnnotation(ts)
	while anno != None:
		if cu.annotations == None:
			cu.annotations = []
		cu.annotations.append(anno)
		anno = readAnnotation(ts)

	tok = ts.getCurrentToken()
	if tok.data == "package":
		ts.getNextToken()
		cu.package = readQualifiedName(ts)
		tok = ts.getCurrentToken()
		if cu.package == None or tok.data != ";":
			raise WAFCompileError("Syntax Error in package name", filepath, tok.lineno, tok.pos, "")
		ts.getNextToken()
	if ts.isEnd():return cu
	tok = ts.getCurrentToken()
	if ts.isEnd():return cu
	if tok.data == "import":
		imp = readImport(ts)
		cu.imports.append(imp)
		tok = ts.getCurrentToken()
		while tok.data == "import":
			imp = readImport(ts)
			if imp == None:
				return None
			cu.imports.append(imp)
			tok = ts.getCurrentToken()
	if ts.isEnd():return cu
	tok = ts.getCurrentToken()
	if ts.isEnd():return cu
	while tok.data == ";":
		tok = ts.getNextToken()
		if ts.isEnd():return cu

	td = readTypeDeclaration(ts)
	if td != None:
		cu.decl.append(td)

	while tok.data == ";":
		tok = ts.getNextToken()
		if ts.isEnd():return cu


	if ts.isEnd():return cu
	tok = ts.getCurrentToken()
	if ts.isEnd():return cu

	if td == None:
		raise WAFCompileError(164, ts.getCurrentToken())
	while td != None:
		#cu.decl.append(td)
		td = readTypeDeclaration(ts)
		if td != None:
			cu.decl.append(td)
		while tok.data == ";":
			tok = ts.getNextToken()
			if ts.isEnd():return cu

		if ts.isEnd():return cu
		tok = ts.getCurrentToken()
		if ts.isEnd():return cu
	return cu
def processJavaFile(filepath,model=False,controller=False):
	print "FP :",filepath
	try:
		posErrors = []
		ts = TokenStream(tokenize(filepath), filepath)
		cu = read_CompilationUnit(ts)
		cu.filepath = filepath
		scu = Analyzer.SHelper.processCompilationUnit(cu,model,controller)
		global scus
		scus.append(scu)
		return scu
	except Exception as inst:
		print "ERROR: Exception in "+filepath
		print inst 		
		
def checkDir(filepath,level,names):
	files = os.listdir(filepath)
	for f in files:
		if f == ".svn":continue
		path = os.path.join(filepath, f)
		if level==1:
			if names[0]=="org" and f=="json":continue
			if names[0]=="server":
				if f!="services":continue
		if level==3:
			if names[0]=="com" and names[1]=="openwaf" and names[2]=="server" and f!="JSONSerializable.java":
				continue
		if os.path.isdir(path):
			names.append(f)
			checkDir(path,level+1,names)
			names.pop()
		else:
			if path[-5:] == ".java":				
				processJavaFile(path)


def processPackage(p):
	for name in p.subpackages:
		processPackage(p.subpackages[name])
	for name in p.types:
		cls = p.types[name]
		if isinstance(cls, Analyzer.SClass):
			Analyzer.SHelper.processSClass(cls)
		elif isinstance(cls, Analyzer.SInterface):
			Analyzer.SHelper.processSInterface(cls)
		elif isinstance(cls, Analyzer.SEnum):
			Analyzer.SHelper.processSEnum(cls)
		elif isinstance(cls, Analyzer.SAnnotationType):
			#print "Not Processing Annotation Type", cls.name
			pass
		else:
			print "What is this ", cls
			sys.exit(0)
def compileLib():	
	for path in WAFConfig.getLibPaths():
		checkDir(path,0,[])
	Analyzer.SGlobal.initBasicType()
	processPackage(Analyzer.SGlobal.root)
	for scu in scus:
		Semantic.SA.checkCompilationUnit(scu)
def getJSForLib():
	import Java2js
	p_proto = Java2js.getFormatedCode(Java2js.writePackagePrototypeInstance(Analyzer.SGlobal.root), 0)
	t_proto = Java2js.getFormatedCode(Java2js.writeTypePrototypeInstance(Analyzer.SGlobal.root), 0)
	class_code = []
	classes=[]
	for scu in scus:
		Java2js.SA.collectTypes(scu, classes)
	max_depth=0
	for c in classes:
		max_depth= max(c.getIneheritanceLevel(),max_depth)
	
	icode=[]
	cls=Analyzer.SHelper.getClassOnFullName("java.lang.Object")
	Java2js.writePackageInstanceCreationForType(cls,["java","lang"], icode)
	icode += Java2js.SA.checkType(cls)
	cls=Analyzer.SHelper.getClassOnFullName("com.openwaf.client.core.Client")
	Java2js.writePackageInstanceCreationForType(cls,["com","openwaf","client","core"], icode)
	icode += Java2js.SA.checkType(cls)	
	icode+=Analyzer.SGlobal.static_field_lines+Analyzer.SGlobal.static_code_calls
	cls=SHelper.getClassOnFullName("com.openwaf.client.core.Client")
	if cls==None:
		raise Exception("Can not find class com.openwaf.client.core.Client")	
	method=cls.getMethodWithThisAccess("init",[],True,None,None)
	icode.append(cls.getPrototype()+".$."+method.method.getJSName()+"();")
	Analyzer.SGlobal.static_field_lines=[]
	Analyzer.SGlobal.static_code_calls=[]
	Analyzer.SGlobal.necessory_classes_processed=True
	bd_code=Java2js.getFormatedCode(icode, 0)
	
	for level in range(max_depth+1):
		for c in classes:
			if c.getIneheritanceLevel()==level:
				code = Java2js.SA.checkType(c)
				if c.fullname=="com.openwaf.client.core.Client":continue
				if c.fullname=="java.lang.Object":continue
				class_code.append(Java2js.getFormatedCode(code, 0))
	
	fcode = []
	fcode.append(WAFConfig.getWAFRootObjectName() + "={};")
	if WAFConfig.isStringAggregateEnabled()==True:
		line=WAFConfig.getWAFRootObjectName() + ".$=["
		count=0
		str_ar=[]
		l=len(Literal.strings)
		for i in range(l):			
			for key in Literal.strings:
				i=Literal.strings[key]
				if i==count:
					str_ar.append(key)
					count+=1
					break		
		line+=",".join(str_ar)
		line+="];"
		fcode.append(line)	
	fcode.append(StaticCode.getCode())
	fcode.append(p_proto)
	fcode.append(bd_code)
	fcode.append(t_proto)
	
	fcode=fcode+class_code
	n_lines=[]
	if WAFConfig.isMinify()==False:
		line="\n".join(fcode);
		lines=line.split("\n");
		for i in range(len(lines)):
			if len(lines[i].rstrip())>0:
				if WAFConfig.add_gen_code_line_prefix==True:
					n_lines.append(WAFConfig.gen_code_line_prefix+lines[i].rstrip())
				else:
					n_lines.append(lines[i].rstrip())
	else:
		line="\n".join(fcode);
		lines=line.split("\n");
		for i in range(len(lines)):
			if len(lines[i].rstrip())>0:
				n_lines.append(lines[i].strip())
	return n_lines
def getJSForLib2():
	import Java2js
	fcode=[]
	ext = Java2js.getFormatedCode(Java2js.ExternCreate.getCode(), 0)
	fcode.append(ext);
	cls=SHelper.getClassOnFullName("com.openwaf.core.framework.BlockMethod")
	cons=cls.getConstructor([], None)
	bf_line=WAFConfig.getWAFRootObjectName()+".bf=(new "+cls.getPrototype()+"())."+cons.getJSName()+"();";
	helper_cls=SHelper.getClassOnFullName("com.openwaf.core.framework.RunTimeHelper");	
	cc_method=helper_cls.getMethodWithThisAccess("getClassObject", [SGlobal.stringclass.mytype], True,None, None)
	cc_line=helper_cls.getPrototype()+".prototype."+cc_method.method.getJSName()
	cc_code=Java2js.writeClassInstanceCreation(Analyzer.SGlobal.root, cc_line)	
	fcode=fcode+cc_code
	fcode=fcode+Analyzer.SGlobal.static_field_lines+Analyzer.SGlobal.static_code_calls
	fcode.append(bf_line)
	n_lines=[]
	if WAFConfig.isMinify()==False:
		line="\n".join(fcode);
		lines=line.split("\n");
		for i in range(len(lines)):
			if len(lines[i].rstrip())>0:
				if WAFConfig.add_gen_code_line_prefix==True:
					n_lines.append(WAFConfig.gen_code_line_prefix+lines[i].rstrip())
				else:
					n_lines.append(lines[i].rstrip())
	else:
		line="\n".join(fcode);
		lines=line.split("\n");
		for i in range(len(lines)):
			if len(lines[i].rstrip())>0:
				n_lines.append(lines[i].strip())
	return n_lines